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

文章目录

  • 数据类型与命令
    • 常用
      • 字符串(String)
      • 列表(List)
      • 集合(Set)
      • 有序集合(Sorted Set)
      • 哈希(Hash)
    • 特殊
      • 地理位置(GEO)
      • 流(Stream)
      • 基数统计(HyperLogLog)
      • 位图(Bitmap)

数据类型与命令

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

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

常用

字符串(String)

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

应用场景:

  • 分布式全局自增id

    使用incr递增数字

  • 普通的字符串缓存

  • setnx用于分布式锁

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

常用命令:

命令 用法示例 描述
SET SET key value 赋值,设置key对应的value
如果对一个key执行多次SET操作,则会覆盖之前的值
GET GET key 取值,获取key对应的value
MGET MGET key1 [key2…] 获取所有(一个或多个)给定key的值
MSET MSET key value [key value …] 同时设置一个或多个key-value对
GETSET GETSET key value 赋值并获取旧的值,Redis 6.2.0版本之后,这个命令已经被标记为过时的,可用SET命令 + GET作为参数替代
SETNX SETNX key value 当value不存在时才赋值
SETEX SETEX key seconds value 设置key对应的value,并将key的过期时间设为seconds(以秒为单位)
STRLEN STRLEN key 返回key所储存的字符串值的长度
INCR INCR key 将key中储存的数字值加一
INCRBY INCRBY key increment 将key所储存的值加上给定的增量值(increment)
DECR DECR key 将key中储存的数字值减一
DECRBY DECRBY key decrement 将key所储存的值减去给定的减量值(decrement)
APPEND APPEND 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> 

列表(List)

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

应用场景:

  • 作为栈或队列使用

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

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

常用命令:

命令 用法示例 描述
LPOP LPOP key [count] 移除并获取列表头部的一个或几个元素(从左边移除并获取)
RPOP RPOP key [count] 移除并获取列表尾部的一个或几个元素(从右边移除并获取)
LPUSH LPUSH key value1 [value2…] 向列表左边(头部)添加一个或多个值
RPUSH RPUSH key value1 [value2…] 向列表右边(尾部)添加一个或多个值
LLEN LLEN key 获取列表长度
LRANGE LRANGE key start stop 获取列表指定范围内的元素
LREM LREM key count element 删除列表元素
count > 0 : 从左至右删除和element相等的指定个数的元素
count < 0 : 从右至左删除和element相等的指定个数的元素
count = 0 : 删除所有和element相等的元素
LSET LSET key index value 通过索引设置列表元素的值
LINDEX LINDEX 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> 

问题:

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

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

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

    LPUSH + RPOP

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

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

    RPUSH + RPOP

集合(Set)

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

应用场景:

  • 黑白名单

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

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

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

常用命令:

命令 用法示例 描述
SADD SADD key member1 [member2…] 向集合添加一个或多个成员
SCARD SCARD key 获取集合的成员数
SMEMBERS SMEMBERS key 返回集合中的所有成员
SPOP SPOP key 返回集合中的一个随机元素,并删除该元素
SRANDMEMBER SRANDMEMBER key [count] 返回集合中一个或多个随机元素,不会删除该元素
SREM SREM key member1 [member2] 移除集合中一个或多个元素,不会返回该元素
SISMEMBER SISMEMBER key member 判断元素是否在集合内
SINTER SINTER key1 [key2…] 返回给定所有集合的交集(相同的元素)
SDIFF SDIFF key1 [key2…] 返回给定所有集合在第一个指定的集合中的公共差集(不相同的元素)
SUNION SUNION 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> 

有序集合(Sorted Set)

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

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

应用场景:

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

常用命令:

命令 用法示例 描述
ZADD ZADD key score1 member1 [score2 member2] 向有序集合添加一个或多个成员,或者更新已存在成员的分数
ZCARD ZCARD key 获取有序集合的成员数
ZCOUNT ZCOUNT key min max 返回有序集合中score值在[min,max]区间的元素数量
ZINCRBY ZINCRBY key increment member 集合中对指定成员的分数加上增量 increment
ZSCORE ZSCORE key member 返回有序集合中,成员的分数值
ZRANK ZRANK key member 获得有序集合中member的排名(按分值从小到大),需要注意的是,排名序号是从0开始的
ZREVRANK ZREVRANK key member 获得有序集合中member的排名(按分值从大到小)
ZRANGE ZRANGE key start stop [WITHSCORES] 获得有序集合中指定排名区间成员,按分数递增排序
ZREVRANGE ZREVRANGE key start stop [WITHSCORES] 获得有序集合中指定排名区间成员,按分数递减排序
ZREM ZREM 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"

哈希(Hash)

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

应用场景:

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

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

常用命令:

命令 用法示例 描述
HSET HSET key field value 单个字段赋值,将哈希表key中的字段field的值设为value,如果该field之前有值,则做更新操作
HMSET HMSET key field1 value1 [field2 value2…] 给多个字段赋值
HSETNX HSETNX key field value 只有在字段field不存在时,设置哈希表字段的值
HGET HGET key field 获取存储在哈希表中指定字段的值
HMGET HMGET key field1 [field2…] 获取所有给定字段的值
HGETALL HGETALL key 获取在哈希表中指定key的所有字段和值
HEXISTS HEXISTS key field 查看哈希表key中,指定的字段是否存在
HDEL HDEL key field1 [field2…] 删除一个或多个哈希表字段
HKEYS HKEYS key 获取所有哈希表中的字段
HLEN HLEN key 获取所有哈希表长度(field-value映射数量)
HVALS HVALS 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> 

特殊

地理位置(GEO)

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

应用场景:

1、记录地理位置

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

3、查找"附近的人"

4、搜索某地附近的美食

常用命令:

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

流(Stream)

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

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

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

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

应用场景:

订单处理

消息队列

聊天室

常用命令:

命令 用法示例 描述
XADD XADD key ID field value [field value …] 向队列添加消息,消息由一组或多组field-value组成,如果指定的队列不存在,则先创建一个队列
ID:消息 id,我们使用 * 表示由 redis 生成,可以自定义,但是要自己保证递增性
XREAD XREAD [COUNT count] [BLOCK milliseconds] STREAMS key [key …] id [id …] 从一个或多个Stream中读取消息,可指定读取的数量,是否以阻塞的方式去取,以及从每个Stream读取消息的起始id (不包含指定id)
XLEN XLEN key 获取队列包含的元素数量,即队列长度
XDEL XDEL key ID [ID …] 根据id删除队列中的一条或者多条消息
XRANGE XRANGE key start end [COUNT count] 消息id从小到大,读取队列中给定ID范围的消息
key :队列名
start :开始值, - 表示最小值
end :结束值, + 表示最大值
count :数量
XREVRANGE XREVRANGE key end start [COUNT count] 消息id从大到小,读取队列中给定ID范围的消息
XGROUP CREATE XGROUP CREATE key groupname id-or-$ 创建消费组
key:指定消费的队列名称,如果不存在就创建
groupname:组名
id-or- :指定从哪消费,可指定从具体的 i d 开始消费,如果设置为 : 0 − 0 ,表示从头开始消费,也可设置为 : 指定从哪消费,可指定从具体的id开始消费,如果设置为: 0-0,表示从头开始消费,也可设置为 :指定从哪消费,可指定从具体的id开始消费,如果设置为:00,表示从头开始消费,也可设置为,表示从尾部开始消费,只接受新消息,当前 Stream旧的消息会全部忽略
XGROUP SETID XGROUP SETID key groupname id-or-$ 修改一个消费组从那开始消费
XGROUP DESTROY XGROUP DESTROY key groupname 删除指定消费组
XREADGROUP GROUP XREADGROUP GROUP group consumer [COUNT count] [BLOCK milliseconds] [NOACK] STREAMS key [key …] id [id …] 和XREAD相似,指定消费者组进行读取消息
group:消费组名,需要提前创建
consumer:消费者名,一个消费组可以由多名消费者组成,同时消费一个Stream,会自动创建(也可以使用命令创建),如果消息队列中的消息被消费组的一个消费者消费了,这条消息就不会再被这个消费组的其他消费者读取到
id:这里的id含义比较特殊,在后面解释
XGROUP XGROUP CREATECONSUMER key groupname consumername 创建一个消费组的消费者
XACK XACK 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> 

注意:

使用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。 基数估计就是在误差可接受的范围内,快速计算基数。

应用场景:

估算一个游戏的日活量

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

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

常用命令:

命令 用法示例 描述
PFADD PFADD key element [element…] 添加指定元素到 HyperLogLog中
PFCOUNT PFCOUNT key [key …] 返回给定 HyperLogLog 的基数估算值
PFMERGE PFMERGE 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> 

位图(Bitmap)

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

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

应用场景:

用户签到

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

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

统计用户活跃数量

常用命令:

命令 用法示例 描述
SETBIT SETBIT key offset value 用来设置或者清除某一位上的值,其返回值是原来位上存储的值
key:在初始状态下所有的位都为 0
offset:可根据业务实际需求设计
value:只能是 0 或者 1
GETBIT GETBIT key offset 获得key在offffset处的bit值
BITCOUNT BITCOUNT key [start end [BYTE | BIT]] 获得key的bit位为1的个数
BITOP BITOP 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> 

你可能感兴趣的:(Redis,redis,数据库,数据类型,redis,命令)