除了五中基本的数据类型外,Redis还支持两种特殊的数据类型,第一种 Geo (地理位置):用于存储地理位置相关的数据,例如经纬度、距离等。第二种 Stream (流):是一个高级的列表类型,支持对列表的批量操作,如添加多个元素、获取多个元素等。
Redis Stream是Redis数据结构中的一种,用于处理基于事件的消息流。它提供了一种高度可扩展且高效的方式来处理大量的消息,并且可以很容易地与Redis的其他数据结构集成。它是一个可持久化的、可追溯的、能处理大量数据的消息流。
Redis Stream的基本单位是消息条目(Entry),每个消息条目包含一个消息体(Payload)和一些元数据(Metadata)。在Redis Stream中,消息条目按照时间顺序排列,可以理解为是一个时间线上的序列。
Redis Stream具有以下特点:
Redis Stream在很多场景中都有广泛的应用如:
Redis Stream 的结构图:
Redis Stream 主要用于消息队列(MQ,Message Queue),Redis 本身是有一个 Redis 发布订阅 (pub/sub) 来实现消息队列的功能,但它有个缺点就是消息无法持久化,如果出现网络断开、Redis 宕机等,消息就会被丢弃。发布订阅 (pub/sub) 可以分发消息,但无法记录历史消息。
在 Redis 中发布订阅 (pub/sub) 可以分发消息,但无法记录历史消息,pub/sub(发布/订阅)模式本身并不支持持久化。当一个订阅者(subscriber)订阅了一个频道(channel)后,它将在内存中保存该频道的状态以及接收到的消息。然而,如果订阅者断开了连接或者 Redis 服务器崩溃,它就无法恢复到之前的状态。
而 Redis Stream 提供了消息的持久化和主备复制功能,可以让任何客户端访问任何时刻的数据,并且能记住每一个客户端的访问位置,还能保证消息不丢失。
Redis Stream的核心概念包括:
消息队列相关命令:
消费者组相关命令:
Redis Stream还支持一些高级特性如:
说明:
XADD是一个用于将新元素添加到Redis的有序集合(sorted set)的命令。它可以用于实现简单的消息队列。
语法:
XADD key ID field string [field string ...]
示例:
127.0.0.1:6379> XADD mystream * field1 value1 field2 value2
"1688711543963-0"
127.0.0.1:6379> XADD mystream * name age mr.xiao 25
"1688711752464-0"
127.0.0.1:6379> XRANGE mystream - +
1) 1) "1688711543963-0"
2) 1) "field1"
2) "value1"
3) "field2"
4) "value2"
2) 1) "1688711752464-0"
2) 1) "name"
2) "age"
3) "mr.xiao"
4) "25"
127.0.0.1:6379>
说明:
XTRIM命令用于修剪(trim)有序集合(sorted set)的成员数量,只保留在指定数量范围内的成员。
语法:
XTRIM key MAXLEN [~] count
示例:
XTRIM mystream MAXLEN 1
这个命令将修剪名为"mystream"的有序集合,使其成员数量最多为1。
说明:
XDEL命令用于从Redis的有序集合(sorted set)中删除一个或多个指定成员。
语法:
XDEL key ID [ID ...]
示例:
XDEL mystream 1 2 1688711752464-0
这将从名为"mystream"的有序集合中删除ID为1和2的两个成员。
说明:
XLEN命令用于获取Redis有序集合(sorted set)的长度,即其中包含的成员数量。
语法:
XLEN key
示例:
XLEN mystream
这将返回名为"mystream"的有序集合的长度,即其中包含的成员数量。
说明:
XRANGE命令用于从Redis的有序集合(sorted set)中查询指定范围内的成员,并按照成员属性的值进行排序。
语法:
XRANGE key start end [COUNT count]
示例:
127.0.0.1:6379> XADD emp * name xiaowang age 18
"1688716368510-0"
127.0.0.1:6379> XADD emp * name xiaoli age 23
"1688716375775-0"
127.0.0.1:6379> XADD emp * name ergo age 25
"1688716381880-0"
127.0.0.1:6379> XADD emp * name xiaohei age 27
"1688716387217-0"
127.0.0.1:6379> XADD emp * name xiaosong age 32
"1688716392174-0"
127.0.0.1:6379> XLEN emp
(integer) 5
127.0.0.1:6379> XRANGE emp - + COUNT 2
1) 1) "1688716368510-0"
2) 1) "name"
2) "xiaowang"
3) "age"
4) "18"
2) 1) "1688716375775-0"
2) 1) "name"
2) "xiaoli"
3) "age"
4) "23"
127.0.0.1:6379>
说明:
XREVRANGE命令用于从Redis的有序集合(sorted set)中查询指定范围内的成员,并按照成员属性的值进行逆序排序。
语法:
XREVRANGE key end start [COUNT count]
示例:
127.0.0.1:6379> XADD emp * name xiaowang age 18
"1688716368510-0"
127.0.0.1:6379> XADD emp * name xiaoli age 23
"1688716375775-0"
127.0.0.1:6379> XADD emp * name ergo age 25
"1688716381880-0"
127.0.0.1:6379> XADD emp * name xiaohei age 27
"1688716387217-0"
127.0.0.1:6379> XADD emp * name xiaosong age 32
"1688716392174-0"
127.0.0.1:6379> XLEN emp
(integer) 5
127.0.0.1:6379> XREVRANGE emp + - COUNT 1
1) 1) "1688716392174-0"
2) 1) "name"
2) "xiaosong"
3) "age"
4) "32"
127.0.0.1:6379>
说明:
多个有序集合中读取指定数量的消息,并将这些消息作为流(stream)返回。
语法:
XREAD [COUNT count] [BLOCK milliseconds] STREAMS key [key ...] ID [ID ...]
示例:
127.0.0.1:6379> XREAD COUNT 2 STREAMS mystream emp 0-0 0-0
1) 1) "mystream"
2) 1) 1) "1688714670580-0"
2) 1) "name"
2) "age"
3) "mr.xiao"
4) "25"
2) 1) "emp"
2) 1) 1) "1688716368510-0"
2) 1) "name"
2) "xiaowang"
3) "age"
4) "18"
2) 1) "1688716375775-0"
2) 1) "name"
2) "xiaoli"
3) "age"
4) "23"
127.0.0.1:6379>
说明:
XGROUP CREATE命令用于创建一个新的消费者组
语法:
XGROUP CREATE [CREATE key groupname id-or-$] [SETID key id-or-$] [DESTROY key groupname] [DELCONSUMER k
示例:
从头开始消费:
XGROUP CREATE mystream consumer-group-name 0-0
这个命令将创建一个名为mygroup
的消费者组,并将其添加到名为mystream
的Stream中,并将该消费者组绑定到从第0条消息到第0条消息的范围内。
从尾部开始消费:
XGROUP CREATE mystream consumer-group-name $
这个命令将创建一个名为mygroup
的消费者组,并将其偏移量设置为最新消息的偏移量,确保该消费者组可以正确地处理后续的消息。
说明:
读取指定消费者组的消息。
语法:
XREADGROUP GROUP group consumer [COUNT count] [BLOCK milliseconds] STREAMS key [key ...] ID [ID ...]
示例:
XREADGROUP GROUP consumer-group-name consumer-name COUNT 1 STREAMS mystream >
这个命令将从名为mystream的Stream中读取并锁定第一条未被锁定的消息,并将其分配给名为myconsumer的消费者。