• 【Redis】基于Redis6的数据类型以及相关命令、应用场景整理


    数据类型与命令

    Redis在线测试:http://try.redis.io/,可用来练习大部分命令

    Redis命令官方文档:https://redis.io/commands/

    常用

    字符串(String)

    Redis的String能表达3种值的类型:字符串、整数、浮点数。

    应用场景:

    • 分布式全局自增id

      使用incr递增数字

    • 普通的字符串缓存

    • setnx用于分布式锁

      当value不存在时采用赋值,可用于实现分布式锁

    常用命令:

    命令用法示例描述
    SETSET key value赋值,设置key对应的value
    如果对一个key执行多次SET操作,则会覆盖之前的值
    GETGET key取值,获取key对应的value
    MGETMGET key1 [key2…]获取所有(一个或多个)给定key的值
    MSETMSET key value [key value …]同时设置一个或多个key-value对
    GETSETGETSET key value赋值并获取旧的值,Redis 6.2.0版本之后,这个命令已经被标记为过时的,可用SET命令 + GET作为参数替代
    SETNXSETNX key value当value不存在时才赋值
    SETEXSETEX key seconds value设置key对应的value,并将key的过期时间设为seconds(以秒为单位)
    STRLENSTRLEN key返回key所储存的字符串值的长度
    INCRINCR key将key中储存的数字值加一
    INCRBYINCRBY key increment将key所储存的值加上给定的增量值(increment)
    DECRDECR key将key中储存的数字值减一
    DECRBYDECRBY key decrement将key所储存的值减去给定的减量值(decrement)
    APPENDAPPEND key value如果key已经存在并且是一个字符串, APPEND命令将指定的value追加到该key原来值的末尾
    如果key不存在,则类似SET命令,初始化一个key-value键值对

    示例:

    127.0.0.1:6379> set test-key hello #设置test-key的value为hello
    OK
    127.0.0.1:6379> get test-key #获取test-key的值
    "hello"
    127.0.0.1:6379> 
    127.0.0.1:6379> del test-key #删除key
    (integer) 1
    127.0.0.1:6379> 
    127.0.0.1:6379> get test-key #删除后,获取不存在的key返回nil
    (nil)
    127.0.0.1:6379> 
    127.0.0.1:6379> getset color red #赋值并获取,key没有旧值返回nil
    (nil)
    127.0.0.1:6379> getset color green #赋值并获取之前的值
    "red"
    127.0.0.1:6379> 
    127.0.0.1:6379> set message hello
    OK
    127.0.0.1:6379> append message world #拼接指定字符串至key对应的value后
    (integer) 10
    127.0.0.1:6379> get message
    "helloworld"
    127.0.0.1:6379> 
    127.0.0.1:6379> set count 0
    OK
    127.0.0.1:6379> incr count #将count对应的数值加1
    (integer) 1
    127.0.0.1:6379> incrby count 10 #将count对应的数值加10
    (integer) 11
    127.0.0.1:6379> decr count #将count对应值减1
    (integer) 10
    127.0.0.1:6379> 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    列表(List)

    List列表类型可以存储有序、可重复的元素。Redis列表是简单的字符串列表,按照插入顺序排序,你可以添加一个元素到列表的头部(左边)或者尾部(右边)。

    应用场景:

    • 作为栈或队列使用

    ​ 列表有序,结合不同的命令可以模拟栈(先入后出)或队列(先入先出);

    • 可用于各种列表,比如用户列表、商品列表、评论列表等

    常用命令:

    命令用法示例描述
    LPOPLPOP key [count]移除并获取列表头部的一个或几个元素(从左边移除并获取)
    RPOPRPOP key [count]移除并获取列表尾部的一个或几个元素(从右边移除并获取)
    LPUSHLPUSH key value1 [value2…]向列表左边(头部)添加一个或多个值
    RPUSHRPUSH key value1 [value2…]向列表右边(尾部)添加一个或多个值
    LLENLLEN key获取列表长度
    LRANGELRANGE key start stop获取列表指定范围内的元素
    LREMLREM key count element删除列表元素
    count > 0 : 从左至右删除和element相等的指定个数的元素
    count < 0 : 从右至左删除和element相等的指定个数的元素
    count = 0 : 删除所有和element相等的元素
    LSETLSET key index value通过索引设置列表元素的值
    LINDEXLINDEX key index通过索引获取列表中的元素

    示例:

    127.0.0.1:6379> rpush language java c c++ go python php ruby # 向列表中依次从左至右添加7个元素
    (integer) 7
    127.0.0.1:6379> lpush language scala #从列表左边添加一个元素
    (integer) 8
    127.0.0.1:6379> lrange language 0 7 #查看所有列表数据,注意:下表是从0开始的
    1) "scala"
    2) "java"
    3) "c"
    4) "c++"
    5) "go"
    6) "python"
    7) "php"
    8) "ruby"
    127.0.0.1:6379> rpop language #从右边移除并获取(弹出)一个元素
    "ruby"
    127.0.0.1:6379> llen language
    (integer) 7
    127.0.0.1:6379> lpop language 2 #从左边移除并获取(弹出)两个元素
    1) "scala"
    2) "java"
    127.0.0.1:6379> llen language
    (integer) 5
    127.0.0.1:6379> lrange language 0 4
    1) "c"
    2) "c++"
    3) "go"
    4) "python"
    5) "php"
    127.0.0.1:6379> lindex language 2 #获取列表中坐标为2(第三个)元素
    "go"
    127.0.0.1:6379> 
    127.0.0.1:6379> lset language 2 c# #将坐标为2的元素go替换为c#
    OK
    127.0.0.1:6379> lindex language 2
    "c#"
    127.0.0.1:6379> 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    问题:

    如何使用Redis的List结构实现队列和栈?

    • 队列:(保证添加和移除方向相反即可)

      RPUSH + LPOP (所有数据从尾部/右边添加、从头部/左边移除)<更贴近生活>

      LPUSH + RPOP

    • 栈:(保证添加和移除方向相同即可)

      LPUSH + LPOP (所有数据从头部添加、从头部移除)<更贴近栈的实现>

      RPUSH + RPOP

    集合(Set)

    Redis的Set是String类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。

    应用场景:

    • 黑白名单

      使用SISMEMBER命令可快速判断元素是否在集合内

    • 共同好友、可能认识的人

      使用SINTER、SDIFF命令可判断两个集合的交集、差集

    常用命令:

    命令用法示例描述
    SADDSADD key member1 [member2…]向集合添加一个或多个成员
    SCARDSCARD key获取集合的成员数
    SMEMBERSSMEMBERS key返回集合中的所有成员
    SPOPSPOP key返回集合中的一个随机元素,并删除该元素
    SRANDMEMBERSRANDMEMBER key [count]返回集合中一个或多个随机元素,不会删除该元素
    SREMSREM key member1 [member2]移除集合中一个或多个元素,不会返回该元素
    SISMEMBERSISMEMBER key member判断元素是否在集合内
    SINTERSINTER key1 [key2…]返回给定所有集合的交集(相同的元素)
    SDIFFSDIFF key1 [key2…]返回给定所有集合在第一个指定的集合中的公共差集(不相同的元素)
    SUNIONSUNION key1 [key2…]返回给定所有集合的并集(合并所有集合)

    示例:

    127.0.0.1:6379> sadd languages:lucy java python golang # Lucy掌握的变成语言
    (integer) 3
    127.0.0.1:6379> sadd languages:tony java scala c # Tony掌握的变成语言
    (integer) 3
    127.0.0.1:6379> sadd languages:henry java python php # Henry掌握编程语言
    (integer) 3
    127.0.0.1:6379> scard languages:lucy # 查看集合成员数
    (integer) 3
    127.0.0.1:6379> smembers languages:lucy # 查看集合所有成员
    1) "java"
    2) "golang"
    3) "python"
    127.0.0.1:6379> sdiff languages:lucy languages:henry # 查看Lucy掌握的语言中,Henry不掌握的
    1) "golang"
    127.0.0.1:6379> sdiff languages:henry languages:lucy # 查看Henry掌握的语言中,Lucy不掌握的
    1) "php"
    127.0.0.1:6379> sdiff languages:lucy languages:henry languages:tony # 查看Lucy掌握的语言中,Henry和Tony都不掌握的
    1) "golang"
    127.0.0.1:6379> sinter languages:lucy languages:henry # 查看Lucy和Henry掌握的共同语言
    1) "java"
    2) "python"
    127.0.0.1:6379> sunion languages:lucy languages:henry # 查看Lucy和Henry两人掌握的所有语言
    1) "java"
    2) "golang"
    3) "php"
    4) "python"
    127.0.0.1:6379> 
    127.0.0.1:6379> sismember languages:lucy java # 判断Lucy是否掌握Java (1代表true,0代表false)
    (integer) 1
    127.0.0.1:6379> sismember languages:lucy c
    (integer) 0
    127.0.0.1:6379> 
    127.0.0.1:6379> spop languages:tony # 随机取出并删除一个集合元素
    "scala"
    127.0.0.1:6379> smembers languages:tony 
    1) "java"
    2) "c"
    127.0.0.1:6379> 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    有序集合(Sorted Set)

    Redis 有序集合又叫Zset,和Set一样也是String类型元素的集合,且不允许重复的成员,不同的是每个元素都会关联一个Double类型的分数。Redis正是通过分数来为集合中的成员进行排序。

    有序集合的成员是唯一的,但分数(Score)却可以重复。

    应用场景:

    由于可以按照分值排序,所以适用于各种排行榜。比如:点击排行榜、销量排行榜、搜索排行榜等。

    常用命令:

    命令用法示例描述
    ZADDZADD key score1 member1 [score2 member2]向有序集合添加一个或多个成员,或者更新已存在成员的分数
    ZCARDZCARD key获取有序集合的成员数
    ZCOUNTZCOUNT key min max返回有序集合中score值在[min,max]区间的元素数量
    ZINCRBYZINCRBY key increment member集合中对指定成员的分数加上增量 increment
    ZSCOREZSCORE key member返回有序集合中,成员的分数值
    ZRANKZRANK key member获得有序集合中member的排名(按分值从小到大),需要注意的是,排名序号是从0开始的
    ZREVRANKZREVRANK key member获得有序集合中member的排名(按分值从大到小)
    ZRANGEZRANGE key start stop [WITHSCORES]获得有序集合中指定排名区间成员,按分数递增排序
    ZREVRANGEZREVRANGE key start stop [WITHSCORES]获得有序集合中指定排名区间成员,按分数递减排序
    ZREMZREM key member [member …]移除有序集合中的一个或多个成员

    示例:

    127.0.0.1:6379> zadd examination 80.5 xiaozhao 87.0 xiaoli 76.5 xiaowang 92 xiaozhang # 添加四名学生的考试成绩到有序集合
    (integer) 4
    127.0.0.1:6379> zcard examination # 查看成员数
    (integer) 4
    127.0.0.1:6379> 
    127.0.0.1:6379> zcount examination 80 90 # 统计成绩在80~90分的数量
    (integer) 2
    127.0.0.1:6379> zscore examination xiaoli # 查看小李的成绩
    "87"
    127.0.0.1:6379> zrank examination xiaoli # 查看小李的分数排名(从小到大)<注:起始为0>
    (integer) 2
    127.0.0.1:6379> zrevrank examination xiaoli # 查看小李的分数排名(从大到小)
    (integer) 1
    127.0.0.1:6379> zrange examination 0 2 withscores # 查看成绩倒数三名
    1) "xiaowang"
    2) "76.5"
    3) "xiaozhao"
    4) "80.5"
    5) "xiaoli"
    6) "87"
    127.0.0.1:6379> 
    127.0.0.1:6379> zrevrange examination 0 2 withscores # 查看成绩正数三名
    1) "xiaozhang"
    2) "92"
    3) "xiaoli"
    4) "87"
    5) "xiaozhao"
    6) "80.5"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    哈希(Hash)

    Redis Hash是一个String类型的Field(字段)和Value(值)的映射表,也称作散列表、哈希表、字典,Hash特别适合用于存储对象。

    应用场景:

    • 更适合存储结构化的数据,如对象的存储 ,表数据的映射。

    • 购物车
      以用户id作为key,每位用户创建一个hash存储结构存储对应的购物车信息
      将商品编号作为field,购买数量作为value进行存储

    常用命令:

    命令用法示例描述
    HSETHSET key field value单个字段赋值,将哈希表key中的字段field的值设为value,如果该field之前有值,则做更新操作
    HMSETHMSET key field1 value1 [field2 value2…]给多个字段赋值
    HSETNXHSETNX key field value只有在字段field不存在时,设置哈希表字段的值
    HGETHGET key field获取存储在哈希表中指定字段的值
    HMGETHMGET key field1 [field2…]获取所有给定字段的值
    HGETALLHGETALL key获取在哈希表中指定key的所有字段和值
    HEXISTSHEXISTS key field查看哈希表key中,指定的字段是否存在
    HDELHDEL key field1 [field2…]删除一个或多个哈希表字段
    HKEYSHKEYS key获取所有哈希表中的字段
    HLENHLEN key获取所有哈希表长度(field-value映射数量)
    HVALSHVALS key获取所有哈希表中的值

    示例:

    127.0.0.1:6379> hmset user:zhangfei username zhangfei password 123456 age 23 sex male # 批量给user:zhangfei赋值
    OK
    127.0.0.1:6379> hkeys user:zhangfei # 获取所有的字段名
    1) "username"
    2) "password"
    3) "age"
    4) "sex"
    127.0.0.1:6379> hvals user:zhangfei # 获取所有的值
    1) "zhangfei"
    2) "123456"
    3) "23"
    4) "male"
    127.0.0.1:6379> hexists user:zhangfei address # 检查字段是否存在
    (integer) 0
    127.0.0.1:6379> hexists user:zhangfei age
    (integer) 1
    127.0.0.1:6379> hdel user:zhangfei password # 删除指定字段
    (integer) 1
    127.0.0.1:6379> hkeys user:zhangfei 
    1) "username"
    2) "age"
    3) "sex"
    127.0.0.1:6379> hlen user:zhangfei # 查看field-value映射数量
    (integer) 3
    127.0.0.1:6379> 
    127.0.0.1:6379> hgetall user:zhangfei # 获取所有field以及对应的value
    1) "username"
    2) "zhangfei"
    3) "age"
    4) "23"
    5) "sex"
    6) "male"
    127.0.0.1:6379> 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    特殊

    地理位置(GEO)

    Redis GEO主要用于存储地理位置信息,并对存储的信息进行操作,该功能在Redis 3.2版本新增。

    应用场景:

    1、记录地理位置

    2、计算外卖配送-骑手距离

    3、查找"附近的人"

    4、搜索某地附近的美食

    常用命令:

    命令用法示例描述
    GEOADDGEOADD key longitude latitude member [longitude latitude member …]用于存储指定的地理空间位置,可以将一个或多个经度(longitude)、纬度(latitude)、位置名称(member)添加到指定的 key 中
    GEOPOSGEOPOS key member [member …]从给定的 key 里返回所有指定名称(member)的位置(经度和纬度),不存在的返回 nil。
    GEODISTGEODIST key member1 member2 [m|km|ft|mi]返回两个给定位置之间的距离
    m :米,默认单位
    km :千米
    mi :英里
    ft :英尺
    GEORADIUSGEORADIUS key longitude latitude radius [m|km|ft|mi]以给定的经纬度为中心, 返回键包含的位置元素当中, 与中心的距离不超过给定最大距离的所有位置元素
    GEORADIUSBYMEMBERGEORADIUSBYMEMBER key member radius以给定的成员为中心,返回键包含的位置元素当中, 与中心的距离不超过给定最大距离的所有位置元素

    示例:

    127.0.0.1:6379> GEOADD Sicily 13.361389 38.115556 "Palermo" 15.087269 37.502669 "Catania" # 给西西里岛添加两座地点:巴勒莫和卡塔尼亚,并分别指定经纬度
    (integer) 2
    127.0.0.1:6379> GEODIST Sicily Palermo Catania km # 计算两个地点的距离
    "166.2742"
    127.0.0.1:6379> GEORADIUS Sicily 15 37 200 km # 列举以(15,37)为中心,相距200km的地点
    1) "Palermo"
    2) "Catania"
    127.0.0.1:6379> GEORADIUS Sicily 15 37 200 km WITHDIST # 列举以(15,37)为中心,相距200km的地点,并计算其距离
    1) 1) "Palermo"
       2) "190.4424"
    2) 1) "Catania"
       2) "56.4413"
    127.0.0.1:6379> GEOPOS Sicily Palermo # 查询指定地点的经纬度
    1) 1) "13.36138933897018433"
       2) "38.11555639549629859"
    127.0.0.1:6379> 
    127.0.0.1:6379> GEORADIUSBYMEMBER Sicily Palermo 200 km # 列举以指定地点为中心,相距200km的地点(结果包含本身)
    1) "Palermo"
    2) "Catania"
    127.0.0.1:6379> 
    127.0.0.1:6379> GEORADIUSBYMEMBER Sicily Palermo 1 km
    1) "Palermo"
    127.0.0.1:6379> 
    127.0.0.1:6379> 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    流(Stream)

    Redis Stream 是 Redis 5.0 版本新增加的数据结构。

    Redis Stream 主要用于消息队列(MQ,Message Queue),Redis 本身是有一个 Redis 发布订阅 (pub/sub) 来实现消息队列的功能,但它有个缺点就是消息无法持久化,如果出现网络断开、Redis 宕机等,消息就会被丢弃。

    简单来说发布订阅 (pub/sub) 可以分发消息,但无法记录历史消息。而 Redis Stream提供了消息的持久化和主备复制功能,可以让任何客户端访问任何时刻的数据,并且能记住每一个客户端的访问位置,还能保证消息不丢失。

    每个Stream都有唯一的名称,它就是 Redis 的 key,在我们首次使用 xadd 指令追加消息时自动创建。

    应用场景:

    订单处理

    消息队列

    聊天室

    常用命令:

    命令用法示例描述
    XADDXADD key ID field value [field value …]向队列添加消息,消息由一组或多组field-value组成,如果指定的队列不存在,则先创建一个队列
    ID:消息 id,我们使用 * 表示由 redis 生成,可以自定义,但是要自己保证递增性
    XREADXREAD [COUNT count] [BLOCK milliseconds] STREAMS key [key …] id [id …]从一个或多个Stream中读取消息,可指定读取的数量,是否以阻塞的方式去取,以及从每个Stream读取消息的起始id (不包含指定id)
    XLENXLEN key获取队列包含的元素数量,即队列长度
    XDELXDEL key ID [ID …]根据id删除队列中的一条或者多条消息
    XRANGEXRANGE key start end [COUNT count]消息id从小到大,读取队列中给定ID范围的消息
    key :队列名
    start :开始值, - 表示最小值
    end :结束值, + 表示最大值
    count :数量
    XREVRANGEXREVRANGE key end start [COUNT count]消息id从大到小,读取队列中给定ID范围的消息
    XGROUP CREATEXGROUP CREATE key groupname id-or-$创建消费组
    key:指定消费的队列名称,如果不存在就创建
    groupname:组名
    id-or- :指定从哪消费,可指定从具体的 i d 开始消费,如果设置为 : 0 − 0 ,表示从头开始消费,也可设置为 : 指定从哪消费,可指定从具体的id开始消费,如果设置为: 0-0,表示从头开始消费,也可设置为 :指定从哪消费,可指定从具体的id开始消费,如果设置为:00,表示从头开始消费,也可设置为,表示从尾部开始消费,只接受新消息,当前 Stream旧的消息会全部忽略
    XGROUP SETIDXGROUP SETID key groupname id-or-$修改一个消费组从那开始消费
    XGROUP DESTROYXGROUP DESTROY key groupname删除指定消费组
    XREADGROUP GROUPXREADGROUP GROUP group consumer [COUNT count] [BLOCK milliseconds] [NOACK] STREAMS key [key …] id [id …]和XREAD相似,指定消费者组进行读取消息
    group:消费组名,需要提前创建
    consumer:消费者名,一个消费组可以由多名消费者组成,同时消费一个Stream,会自动创建(也可以使用命令创建),如果消息队列中的消息被消费组的一个消费者消费了,这条消息就不会再被这个消费组的其他消费者读取到
    id:这里的id含义比较特殊,在后面解释
    XGROUPXGROUP CREATECONSUMER key groupname consumername创建一个消费组的消费者
    XACKXACK key group id [id …]将消息标记为”已处理“
    ACK:acknowledge的缩写,消息队列的一种确认机制,客户端收到消息或处理完业务之后,告知服务端消息已正常消费

    示例:

    127.0.0.1:6379> xadd order * name iphone type "iphone 13 pro max" storage 256GB color blue  # 创建队列order,并添加一条消息流
    "1661169438466-0"
    127.0.0.1:6379> xadd order * name iphone type "iphone 13 pro" storage 128GB color white  # 向Stream中添加消息流
    "1661169496826-0"
    127.0.0.1:6379> xlen order # 查看消息数量
    (integer) 2
    127.0.0.1:6379> xdel order 1661169496826-0 # 根据id删除消息
    (integer) 1
    127.0.0.1:6379> xlen order 
    (integer) 1
    127.0.0.1:6379> xrange order - + # 获取指定范围内的所有消息
    1) 1) "1661169438466-0"
       2) 1) "name"
          2) "iphone"
          3) "type"
          4) "iphone 13 pro max"
          5) "storage"
          6) "256GB"
          7) "color"
          8) "blue"
    127.0.0.1:6379> xread streams order 0-0 # 从起始位置读取所有消息
    1) 1) "order"
       2) 1) 1) "1661169438466-0"
             2) 1) "name"
                2) "iphone"
                3) "type"
                4) "iphone 13 pro max"
                5) "storage"
                6) "256GB"
                7) "color"
                8) "blue"
    127.0.0.1:6379> 
    127.0.0.1:6379> xadd order * name Xiaomi type "Xiaomi 12 ultra" storage 512GB color black 
    "1661224305535-0"
    127.0.0.1:6379> xread streams order 1661169438466-0 # 从大于id:1661169438466-0的地方开始读取所有消息
    1) 1) "order"
       2) 1) 1) "1661224305535-0"
             2) 1) "name"
                2) "Xiaomi"
                3) "type"
                4) "Xiaomi 12 ultra"
                5) "storage"
                6) "512GB"
                7) "color"
                8) "black"
    127.0.0.1:6379> 
    127.0.0.1:6379> xgroup create order warehouse 0-0 # 创建order的消费者组warehouse,指定从队列最开始位置消费
    OK
    127.0.0.1:6379> xinfo stream order # 查看order队列的信息
     1) "length"
     2) (integer) 2
     3) "radix-tree-keys"
     4) (integer) 1
     5) "radix-tree-nodes"
     6) (integer) 2
     7) "last-generated-id"
     8) "1661224305535-0"
     9) "groups"
    10) (integer) 1
    11) "first-entry"
    12) 1) "1661169438466-0"
        2) 1) "name"
           2) "iphone"
           3) "type"
           4) "iphone 13 pro max"
           5) "storage"
           6) "256GB"
           7) "color"
           8) "blue"
    13) "last-entry"
    14) 1) "1661224305535-0"
        2) 1) "name"
           2) "Xiaomi"
           3) "type"
           4) "Xiaomi 12 ultra"
           5) "storage"
           6) "512GB"
           7) "color"
           8) "black"
    127.0.0.1:6379> xinfo groups order # 查看order队列的所有消费组信息
    1) 1) "name"
       2) "warehouse"
       3) "consumers"
       4) (integer) 0
       5) "pending"
       6) (integer) 0
       7) "last-delivered-id"
       8) "0-0"
    127.0.0.1:6379> 
    127.0.0.1:6379> xgroup create order store 0-0
    OK
    127.0.0.1:6379> xgroup createconsumer order store consumer-1 # 手动创建消费者
    (integer) 1
    127.0.0.1:6379> xreadgroup group store consumer-1 count 2 streams order >  # 消费新消息
    1) 1) "order"
       2) 1) 1) "1661169438466-0"
             2) 1) "name"
                2) "iphone"
                3) "type"
                4) "iphone 13 pro max"
                5) "storage"
                6) "256GB"
                7) "color"
                8) "blue"
          2) 1) "1661224305535-0"
             2) 1) "name"
                2) "Xiaomi"
                3) "type"
                4) "Xiaomi 12 ultra"
                5) "storage"
                6) "512GB"
                7) "color"
                8) "black"
    127.0.0.1:6379> 
    127.0.0.1:6379> xreadgroup group store consumer-1 count 2 streams order 0-0 # 读取pending状态的消息
    1) 1) "order"
       2) 1) 1) "1661169438466-0"
             2) 1) "name"
                2) "iphone"
                3) "type"
                4) "iphone 13 pro max"
                5) "storage"
                6) "256GB"
                7) "color"
                8) "blue"
          2) 1) "1661224305535-0"
             2) 1) "name"
                2) "Xiaomi"
                3) "type"
                4) "Xiaomi 12 ultra"
                5) "storage"
                6) "512GB"
                7) "color"
                8) "black"
    127.0.0.1:6379> 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135

    注意:

    使用XREADGROUP时,要在STREAMS选项后面指定id,可以是以下两种类型之一:

    • 特殊标识:>,这意味着消费者只希望接收从未传递给任何其他消费者的消息,这意味着消费新的消息。

    • 任何其他id,即0或任何其他有效id或不完整id,达到的效果是:在处于pending状态的消息列表中,返回大于指定id的消息。因此,基本上,如果id不是 ‘>’ ,那么该命令将只允许客户端访问其pending的条目:即传递给它但尚未确认的消息。注意,在这种情况下,BLOCK和NOACK都被忽略。

    这里比较不易理解,消费最新的消息,使用第一种方式即可,第二种方式,更像是为了处理消息被消费者消费了,但是程序异常或不可抗力的因素导致消息未ack的情况,是一种补偿措施。或者简单地用来查看处于pending状态的消息。

    基数统计(HyperLogLog)

    Redis 在 2.8.9 版本添加了 HyperLogLog 结构。

    Redis HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定 的、并且是很小的。

    什么是基数?

    比如数据集 {1, 3, 5, 7, 5, 7, 8}, 那么这个数据集的基数集为 {1, 3, 5 ,7, 8},基数(不重复元素)为5。 基数估计就是在误差可接受的范围内,快速计算基数。

    应用场景:

    估算一个游戏的日活量

    估算一个游戏公司旗下多款游戏的日活总量

    估算一个网站被多少用户访问过

    常用命令:

    命令用法示例描述
    PFADDPFADD key element [element…]添加指定元素到 HyperLogLog中
    PFCOUNTPFCOUNT key [key …]返回给定 HyperLogLog 的基数估算值
    PFMERGEPFMERGE destkey sourcekey [sourcekey …]将多个 HyperLogLog 合并为一个 HyperLogLog

    示例:

    127.0.0.1:6379> pfadd numbers 1 3 2 5 3 4 6 9 10 # 添加元素
    (integer) 1
    127.0.0.1:6379> pfcount numbers # 查看基数预估值
    (integer) 8
    127.0.0.1:6379> 
    
    • 1
    • 2
    • 3
    • 4
    • 5

    位图(Bitmap)

    在平时开发过程中,经常会有一些 bool 类型数据需要存取。比如记录用户一年内签到的次数,签了是 1,没签是 0。如果使用 key-value 来存储,那么每个用户都要记录 365 次,当用户成百上亿时,需要的存储空间将非常巨大。为了解决这个问题,Redis 提供了位图结构。

    位图(Bitmap)同样属于 string 数据类型。Redis 中一个字符串类型的值最多能存储 512 MB 的内容,每个字符串由多个字节组成,每个字节又由 8 个 Bit 位组成。位图结构正是使用“位”来实现存储的,它通过将比特位设置为 0 或 1来达到数据存取的目的,这大大增加了 value 存储数量。

    应用场景:

    用户签到

    统计一个月内每天都登陆过游戏的用户

    统计超过一个月未登录游戏的用户

    统计用户活跃数量

    常用命令:

    命令用法示例描述
    SETBITSETBIT key offset value用来设置或者清除某一位上的值,其返回值是原来位上存储的值
    key:在初始状态下所有的位都为 0
    offset:可根据业务实际需求设计
    value:只能是 0 或者 1
    GETBITGETBIT key offset获得key在offffset处的bit值
    BITCOUNTBITCOUNT key [start end [BYTE | BIT]]获得key的bit位为1的个数
    BITOPBITOP operation destkey key [key …]对多个key 进行逻辑运算后存入destkey中
    语法:operation 可以是 AND 、 OR 、 NOT 、 XOR 这四种操作中的任意一种:

    BITOP AND destkey key [key …]:对一个或多个key求逻辑与&,并将结果保存到 destkey
    BITOP OR destkey key [key …]:对一个或多个key求逻辑或|,并将结果保存到 destkey
    BITOP XOR destkey key [key …]:对一个或多个key求逻辑异或^,并将结果保存到destkey
    BITOP NOT destkey key:对给定key求逻辑非~,并将结果保存到destkey
    除了 NOT 操作之外,其他操作都可以接受一个或多个 key 作为输入
    命令的返回值表示存储在目标键中的字符串的大小

    示例:

    127.0.0.1:6379> setbit user:sign:1000 20220101 1 # 模拟用户签到
    (integer) 0
    127.0.0.1:6379> setbit user:sign:1000 20220102 1
    (integer) 0
    127.0.0.1:6379> setbit user:sign:1000 20220104 1
    (integer) 0
    127.0.0.1:6379> getbit user:sign:1000 20220102 # 判断用户是否签到
    (integer) 1
    127.0.0.1:6379> bitcount user:sign:1000 # 统计用户签到次数
    (integer) 3
    127.0.0.1:6379> setbit login_09_19 100 1 # 设置9.19有四位用户登录,9.20有三位用户登录
    (integer) 0
    127.0.0.1:6379> setbit login_09_19 101 1
    (integer) 0
    127.0.0.1:6379> setbit login_09_19 102 1
    (integer) 0
    127.0.0.1:6379> setbit login_09_19 103 1
    (integer) 0
    127.0.0.1:6379> setbit login_09_20 100 1
    (integer) 0
    127.0.0.1:6379> setbit login_09_20 101 1
    (integer) 0
    127.0.0.1:6379> setbit login_09_20 103 1
    (integer) 0
    127.0.0.1:6379> bitop and login_in_09_19_and_20 login_09_19 login_09_20 # 计算9.19和9.20两天都登陆过的用户
    (integer) 13
    127.0.0.1:6379> bitcount login_in_09_19_and_20 # 查看9.19和9.20两天都登陆过的用户
    (integer) 3
    127.0.0.1:6379> bitop or login_in_09_19_or_20 login_09_19 login_09_20 # 计算两天登录过的用户总数
    (integer) 13
    127.0.0.1:6379> bitcount login_in_09_19_or_20
    (integer) 4
    127.0.0.1:6379> 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
  • 相关阅读:
    ADB命令
    云原生 | 企业内使用 CoreDNS 构建高性能、插件化的DNS服务器
    《Python 3网络爬虫开发实战 》崔庆才著 第五章笔记
    【牛牛送书 | 第二期】《ChatGPT 驱动软件开发:AI 在软件研发全流程中的革新与实践》
    我与Vue.js 2.x 的七年之痒
    帮我看看这是什么代码
    第20篇 2D绘图(十)图形视图框架(下)
    mac-m1-docker安装nacos异常
    OpenCV实现手势音量控制
    经典算法-----汉诺塔问题
  • 原文地址:https://blog.csdn.net/sinat_14840559/article/details/126609526