美文网首页
redis初识

redis初识

作者: 云师兄 | 来源:发表于2018-02-19 11:54 被阅读23次

    redis典型应用场景

    1. 缓存系统

    image.png

    2. 计数器

    image.png

    3. 消息队列系统

    image.png

    4.排行榜

    image.png

    5.社交网络

    image.png

    6.实时系统

    image.png

    Redis Api的使用和理解

    通用命令

    1. keys * 列出所有键值,keys后面跟的是通配符
    2. dbsize 键的个数
    3. exists key 检查key是否存在
    4. del key 删除key
    5. expire key seconds // key在seconds秒后过期
    6. ttl key // 查询key的过期时间
    7. persist key // 去掉key的过期时间
    8. type key // 返回key的类型

    单线程

    redis在一个瞬间只能执行一条命令。
    单线程为什么这么快?

    1. 纯内存
    2. 非阻塞IO
    3. 避免线程切换和竞态消耗

    字符串类型

    使用场景:缓存、计数器、分布式锁...
    相关涉及命令:get key,set key value,del key
    由于redis内部会把整型自动转换为字符串类型,即整型也被看做字符串类型,下面是整型的相关api:
    incr key // key自增1,若key不存在,自增后get(key)=1
    decr key // key自减1
    incrby key k // key自增k
    decrby key k // key自减k

    set,setnx,setxx三种的区别:
    set key value // 不管key是否存在都设置
    setnx key value // key不存在才进行设置
    set key value xx // key存在才进行设置

    mget,mset的区别:
    mget key1 key2 key3 //批量获取key,原子操作,实现图如下:


    image.png

    从图中可以得知一次mget请求获取多个参数的时候是比较高效的。

    getset,append,strlen三个命令的区别:
    getset key newvalue // set key newvalue并返回旧的value
    append key value // 将value追加到旧的value
    strlen key // 返回字符串的长度,UTF-8中一个中文占两个字节

    incrbyfloat,getrange,setrange三个命令的区别:
    incrbyfloat key 3.5 //增加key对应的值为3.5
    getrange key start end //获取字符串指定下标所有的值
    setrange key index value // 设置指定下标所有对应的值

    字符串总结


    image.png

    哈希类型

    哈希键值结构如下:


    image.png

    hget,hset,hdel:
    hget key field // 获取hash key对应的field的value
    hset key field // 设置hash key对应的field的value
    hdel key field // 删除hash key对应的field的value

    hexists,hlen:
    hexists key field // 判断hash key是否有field
    hlen key // 获取hash key field的数量

    hmget,hmset:
    hmget key field1 field2 ... fieldN // 批量获取hash key的一批field对应的值
    hmset key field1 value1 field2 value2... fileldN valueN //批量设置hasn key的一批field value

    hgetall,hvals,hkeys:
    hgetall key // 返回hash key对应所有的field和value
    hvals key // 返回hash key对应所有的field的value
    hkeys key // 返回hash key对应所有field
    hsetnx key field value // 设置hash key对应field的value,如果field已经存在,则失败
    hincrby key field intCounter // hash key对应的field的value自增intCounter
    hincrbyfloat key field floatCounter // hincrby浮点数版

    list类型

    rpush key value1 value2 ... valueN //从列表右端插入值(1-N)
    lpush key value1 value2 ... valueN //从列表左端插入值(1-N)
    insert key before|after value newValue // 在list指定的值前后插入newValue
    lpop key // 从列表左侧弹出一个item
    rpop key // 从列表右侧弹出一个item
    lrem key count value // 根据count的值,从列表中删除所有value相等的项。如果count大于0,从左到右,删除最多count个value相等的项;如果count小于0,从右到左,删除最多math.abs(count)个value相等的项;如果count=0,删除所有value相等的项。
    ltrim key start end // 按照索引范围修剪列表
    lrange key start end //包含end,获取列表指定索引范围内所有item
    index key index // 获取列表指定索引的item
    llen key // 获取列表长度
    lset key index newValue // 设置列表指定索引值为newValue

    慢查询

    redis客户端访问的流程如下图所示,慢查询发生在第三步。


    屏幕快照 2018-05-30 下午9.06.38.png

    由上图可知,客户端查询超时并不一定是慢查询导致的。上述1到4步每一步都有可能导致客户端查询超时。

    pipeline(流水线)

    对于批量对redis执行get,set操作,为提高效率可以使用mget,mset命令。但是如果想批量执行hset,hget等操作哈希类型的命令,则没有对应的批量操作的方法(hmset命令是针对同一个key进行的批量操作,实际要求是对不同的key和value进行批量操作,此时只能使用pipeline来做),为此提出了流水线命令。批量将请求打包后发送,并将执行结果打包一次返回。


    屏幕快照 2018-05-28 下午1.32.40.png

    通过jedis来使用pipeline示例代码如下:


    屏幕快照 2018-05-28 下午1.44.43.png

    redis安装

    image.png

    redis可执行文件说明

    image.png
    image.png

    下面是一个具体的例子,通过第三方应用的api来获取天气数据:
    首先我们在项目的pom.xml文件中添加必要的依赖:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    

    首先编写配置类RestConfiguration.java

    package com.yun.hello.config;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.web.client.RestTemplateBuilder;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.client.RestTemplate;
    
    @Configuration
    public class RestConfiguration {
    
        @Autowired
        private RestTemplateBuilder restTemplateBuilder;
    
        @Bean
        public RestTemplate restTemplate(){
            return restTemplateBuilder.build();
        }
    }
    

    接下来我们实现请求天气数据api并且将返回值保存到redis中,在下面的例子中我们使用注入的restTemplate对象来发起restful 请求,使用StringRedisTemplate对象把获取的天气数据保存到redis缓存中。

    package com.yun.hello.service.weather;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.redis.core.StringRedisTemplate;
    import org.springframework.data.redis.core.ValueOperations;
    import org.springframework.http.ResponseEntity;
    import org.springframework.stereotype.Service;
    import org.springframework.web.client.RestTemplate;
    
    import java.util.concurrent.TimeUnit;
    
    @Service
    public class WeatherDataCollectionServiceImpl implements WeatherDataCollectionService {
    
        private static String WEATHER_URI="http://wthrcdn.etouch.cn/weather_mini?";
        private static final Long TIME_OUT = 1800L;//30 minutes
    
        @Autowired
        private RestTemplate restTemplate;
    
        @Autowired
        private StringRedisTemplate stringRedisTemplate;
    
        @Override
        public void syncDataByCityId(String cityId) {
            String uri = WEATHER_URI +"citykey="+ cityId;
    
            this.saveWeatherData(uri);
        }
    
        private void saveWeatherData(String uri) {
            String key = uri;
            String resBody= null;
    
            ResponseEntity<String> responseEntity = restTemplate.getForEntity(uri,String.class);
            if(responseEntity.getStatusCodeValue() == 200){
                resBody = responseEntity.getBody();
            }
    
            ValueOperations<String, String> ops = stringRedisTemplate.opsForValue();
            // 数据写入缓存
            ops.set(key,resBody,TIME_OUT, TimeUnit.SECONDS);
        }
    
    }
    
    

    相关文章

      网友评论

          本文标题:redis初识

          本文链接:https://www.haomeiwen.com/subject/bjsitftx.html