Redis入门教程详解

目录
  • redis
    • 一、redis基本数据结构
      • 1. 字符串 (string)
      • 2. 散列(hash)
      • 3. 列表(list)
      • 4. 集合(set)
      • 5. 有序集合(sorted set)
    • 二、redis的高级数据结构
      • 1. hyperloglog
      • 2. geo
      • 3. bitmap
    • 三、redis 高级特性
      • 1. redis事务
      • 2. 发布订阅
      • 3. 脚本
      • 4. redis stream
    • 四、redis使用场景
      • 1. 业务数据缓存
      • 2. 业务数据处理
      • 3. 全局一致计数
      • 4. 高效统计计数
      • 5. 发布订阅与stream
      • 6. 分布式锁
    • 五、redis的java客户端
      • 1. jedis
      • 2. lettuce
      • 3. redission
    • 六、项目集成
      • 1. springmvc项目可以引入spring data redis
      • 2. springboot接入(默认使用的lettuce)
      • 3. spring cache 集成redis
    • 番外:

    redis

    redis是一个开源(bsd许可)的内存数据结构存储,用作数据库、缓存和消息代理。redis提供数据结构,如strings, hashes, lists, sets, sorted sets with range queries, bitmaps, hyperloglogs, geospatial indexes, and streams.。redis具有内置复制、lua脚本、lru eviction、事务和不同级别的磁盘持久性,并通过redis sentinel和redis cluster的自动分区提供高可用性。

    一、redis基本数据结构

    1. 字符串 (string)

    字符串类型是redis中最为基础的数据存储类型,它在redis中是二进制安全的,这意味着该类型可以接受任何格式的数据,如jpeg图像数据或json对象描述信息等。在redis中字符串类型的value最多可以容纳的数据长度是512m。

    常用命令:

    • set key value 设置值
    • get key 获取值
    • getset 将给定的值设置进去,并返回旧值
    • mget key1 key2… 获取一个或多个key的值
    • setnx key value 当key不存在时才设置值
    • incr key 将key存储的值+1
    • incrby key increment 将 key 所储存的值加上给定的增量值(increment)
    • decr key 将key存储的值-1
    • decrby key increment 将 key 所储存的值减去给定的增量值(increment)
    • strlen key 返回key所存储的字符串的长度

    注意:

    1.字符串append命令会使用更多的内存

    2.整数共享:如果能使用整数,就尽量使用整数

    3.整数精度问题:redis能保证16位精度,17-18位的大整数就会丢失精度

    2. 散列(hash)

    redis中hash类型可以看成句又string key和string value的map容器。所以该类型非常适合存储对象的信息。

    常用命令:

    • hset key field value
    • hget key field
    • hmset key field1 value1 [field2 value2 ] 同时set多个field值
    • hmget key field1 [field2]
    • hgetall key 获取key的所有值
    • hincrby key field increment 给指定的key的field增加给定的增量值(increment)
    • hkeys key 获取某个key的所有field
    • hvals key 获取某个key的所有value
    • hlen key 获取hash表中字段的数量
    • hexists key field 查看hash表中的字段是否存在
    • hdel key field1 [field2] 删除一个或多个hash表字段

    3. 列表(list)

    在redis中,list类型是按照插入顺序排序的字符串链表。和数据库结构中的普通链表一样,可以在头部和尾部添加新的元素。在插入时如果键不存在,redis将为该键创建一个新的链表。与此相反,如果链表中所有的元素均被移除,那么该键也会被从数据库中删除。

    常用命令:

    • lpush key value1 [value2] 将一个值或多个值插入到列表头部
    • rpush key value1 [value2] 将一个值或多个值插入到列表尾部
    • lrange key start stop 获取列表指定范围的元素
    • lpop key 移出并获取列表中的第一个元素
    • rpop key 移出并获取列表中的最后一个元素
    • blpop key1 [key2 ] timeout 阻塞性的移出并获取列表的第一个元素,如果没有元素就会阻塞到超时或有元素为止
    • brpop key1 [key2 ] timeout 阻塞性的移出并获取列表的最后一个元素,如果没有元素就会阻塞到超时或有元素为止
    • lindex key index 通过索引位置获取列表中的元素
    • llen key 获取列表长度
    • lset key index value 通过索引位置设置值
    • ltrim key start stop 对一个列表进行修剪,只保留指定区间的元素,区间外的都删除掉

    4. 集合(set)

    redis 的 set 是 string 类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。redis 中集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 o(1)。集合中最大的成员数为 2^32 – 1

    常用命令:

    • sadd key member1 [member2] 向集合中添加元素
    • scard key 获取集合的成员数
    • sdiff key1 [key2] 返回第一个集合与其他集合之间的差异
    • sinter key1 [key2] 返回给定所有集合的交集
    • sunion key1 [key2] 返回给定集合的并集
    • sismember key member 判断member元素是否是集合中的成员
    • smembers key 返回集合中所有成员
    • spop key 移除并返回集中中的一个随机元素
    • srandmember key [count] 返回集合中一个或多个随机数
    • srem key member1 [member2] 移除集合中一个或多个成员

    5. 有序集合(sorted set)

    redis 有序集合和集合一样也是 string 类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个 double 类型的分数。redis 正是通过分数来为集合中的成员进行从小到大的排序。

    常用命令:

    • zadd key score1 member1 [score2 member2] 向有序集合中添加一个或多个成员,或更新已有成员的分数
    • zcard key 获取有序集合中的成员数量
    • zrange key start end [withscores] 通过索引区间返回有序集合中的成员
    • zrevrange key start stop [withscores] 通过索引区间返回有序集合中的成员,分数从高到低
    • zrangebyscore key min max [withscores] [limit] 通过分数返回有序集合指定区间内的成员
    • zrevrangebyscore key min max [withscores] [limit] 通过分数返回有序集合指定区间内的成员,分数由高到低排序
    • zrem key member [member …] 移除
    • zremrangebyrank key start stop 移除给定排名区间的所有成员
    • zremrangebyscore key min max 移除给定分数区间的所有成员
    • zscore key member 返回有序集合中成员的分数

    二、redis的高级数据结构

    1. hyperloglog

    redis 在 2.8.9 版本添加了 hyperloglog 结构。redis hyperloglog是用来做基数统计的算法,hyperloglog的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定 的、并且是很小的。不过这个是估算,有一定的误差。

    基数计算指的是统计一批元素中不重复元素的个数,比如uv的统计。实现基数统计最常见的是用set这种数据结构。但是大数据量下set会占用很大的存储空间。

    常用命令:

    • pfadd key element [element …] 添加指定元素到hyperloglog 中
    • pfcount key [key …] 返回给定key的基数估算值
    • pfmerge destkey sourcekey [sourcekey …] 将多个hyperloglog 合为一个

    2. geo

    redis geo主要用于存储地理位置信息,并对其进行操作。该功能在redis3.2版本增加

    常用命令:

    • geoadd key longitude latitude member [longitude latitude member …] 添加地理位置坐标
    • geopos key member [member …] 返回指定member的经纬度
    • geodist key member1 member2 [m|km|ft|mi] 计算两个位置的距离 后面的是单位

    m【米】 km【千米】 ft【英尺】 mi【英里】

    • georadius key longitude latitude radius m|km|ft|mi [withcoord] [withdist] [withhash] [count count] [asc|desc] [store key] [storedist key] 以给定的经纬度为中心,返回键包含的元素中,与中心距离不超过给定最大距离的所有位置元素
    • georadiusbymember key member radius m|km|ft|mi [withcoord] [withdist] [withhash] [count count] [asc|desc] [store key] [storedist key] 同上,只不过中心位置的传参由经纬度变成了member
    • geohash key member [member …] 获取一个或多个元素的geohash值

    3. bitmap

    bitmap的原理上一篇已经讲过了,它可以用作大数据量的存储,不过存储的内容只能是0或1. 可以使用在10亿用户的在线状态,1代表在线,0代表离线。

    value值只能是0、1

    • setbit key offset value
    • getbit key offset
    • bitcount key 获取值为1的个数

    三、redis 高级特性

    1. redis事务

    redis的事务与数据库的事务概念不同,redis会将一个事务中的所有命令序列化,然后按顺序执行。redis不可能在一个redis事务的执行过程中插入执行另一个客户端发出的请求,事务中任意命令失败不影响其他命令的执行,也不会回滚。

    2. 发布订阅

    发布订阅是一种通信模式,发送者发送消息,订阅者接受消息。客户端可以订阅多个频道,然后有新消息发送给频道,订阅该频道的客户端就都能收到消息。

    常用命令:

    • subscribe channel [channel …] 订阅一个或多个频道
    • psubscribe pattern [pattern …] 订阅一个或多个符合给定模式的频道
    • publish channel message 将消息发送到指定通道
    • unsubscribe [channel [channel …]] 退订给定的频道
    • punsubscribe channel [channel …] 退订所有给定模式的频道。

    3. 脚本

    redis 脚本通过lua解释器来执行脚本,redis 2.6 版本通过内嵌支持lua环境

    基本语法如下:
    eval script numkeys key [key …] arg [arg …]

    例子:

    eval "return {keys[1],keys[2],argv[1],argv[2]}" 2 key1 key2 first second
    

    4. redis stream

    redis stream是5.0版本新增的数据结构。redis stream主要用于消息队列,redis本身有一个发布/订阅功能,但是它有一个缺点,消息没有持久化,如果网络中断或宕机,数据就会丢失。

    redis stream提供了消息的持久化和主备复制功能,它有一个消息链表,把所有加入的消息都串起来,每个消息都有唯一的id和内容。

    常用命令:

    • xadd key id field value [field value …] 添加消息

    xadd mystream * name sa surname occc (*代表id由redis生成)

    • xdel key id [id ..] 删除消息
    • xrange key start end [count count] 查看消息

    xrange mystream – + (- 代表最小值,+ 代表最大值)

    • xgroup [create key groupname id-or-$] [setid key groupname id-or-$] [destroy key groupname] [delconsumer key groupname consumername] 创建消费者组

    从头开始消费:

    xgroup create mystream consumer-group-name 0-0

    从尾部开始消费,只接受新消息

    xgroup create mystream consumer-group-name $

    • xreadgroup group group consumer [count count] [block milliseconds] [noack] streams key [key …] id [id …] 从消费者组读取消息

    xreadgroup group consumer-group-name consumer-name count 1 streams mystream

    第二个group :消费组名
    consumer: 消费者名
    count :读取数量
    milliseconds : 阻塞毫秒数
    key :队列名
    id:消息id

    四、redis使用场景

    1. 业务数据缓存

    1.通用数据缓存:string、list

    2.等会话缓存、token、session缓存

    2. 业务数据处理

    1.非严格一致性要求的数据

    2.业务操作去重:订单处理的幂等校验业务数据排序

    3. 全局一致计数

    1.全局流控

    2.秒杀时库存计算

    3.全局id生成

    4. 高效统计计数

    1.id、ip等使用bitmap操作

    2.使用hyperloglog进行uv、pv等非精确性的统计

    5. 发布订阅与stream

    用于消息发布订阅模式

    6. 分布式锁

    1.获取锁

    set key my_random_value nx px 30000
    

    2.释放锁,需要用到lua脚本保证原子性

    if redis.call("get",keys[1])==argv[1] then
       return redis.call("del",keys[1])
    else
      return 0
    end

    五、redis的java客户端

    1. jedis

    基于bio、线程不安全,需要配置连接池管理连接

    2. lettuce

    目前主流推荐的驱动,基于netty nio,api线程安全

    3. redission

    基于netty nio,api线程安全。大量丰富的分布式功能,如分布式的基本数据类型和锁。

    六、项目集成

    1. springmvc项目可以引入spring data redis

    maven依赖

    <dependency>
                <groupid>org.springframework.data</groupid>
                <artifactid>spring-data-redis</artifactid>
                <version>2.1.2.release</version>
    </dependency>

    核心是redistemplate(可以配置基于jedis、lettuce、redisson),封装了基本的redis命令。

    2. springboot接入(默认使用的lettuce)

    <dependency>
    			<groupid>org.springframework.boot</groupid>
    			<artifactid>spring-boot-starter-data-redis</artifactid>
    </dependency>

    配置spring.redis

    如:spring.redis.host=127.0.0.1

    3. spring cache 集成redis

    1.启用spring cache

    @enablecaching

    2.方法上添加缓存注解

     @override
        @cacheable(value = "usercache")
        public user getuser(integer id) {
            return usermapper.getuser(id);
        }

    3.配置rediscache

    @configuration
    public class cacheconfig {
    
        @bean
        public rediscachemanager cachemanager(redisconnectionfactory redisconnectionfactory) {
            return rediscachemanager.create(redisconnectionfactory);
        }
    }

    番外:

    1.redis到底是单线程,还是多线程?

    这个问题有坑。首先redis作为一个进程来讲是多个线程的。比如redis通过多线程方式在后台删除对象、以及通过 redis模块实现的阻塞命令等.单线程的地方在于探测哪个接收完了请求数据->数据处理->返回数据。而其他耗时操作是用了其他线程。

    探测哪个客户端的请求接受完了,使用的是io多路复用模型,“多路”是指多个网络连接,“复用”是复用同一个线程。

    2.为什么io模块在redis6之前是单线程?

    因为redis是基于内存的操作,cpu不是瓶颈,瓶颈在于机器内存的大小或网络带宽。
    3. redis6之后的多线程是什么?

    io模型使用了多线程的nio模型,内存处理线程也还是单线程。

    以上就是redis详解的详细内容,更多关于redis的资料请关注www.887551.com其它相关文章!

    (0)
    上一篇 2022年3月21日
    下一篇 2022年3月21日

    相关推荐