介绍
Redis stream是redis 5.0版本新增加的数据结构。
Redis stream主要用来消息队列,Redis本身是有一个Redis(pub/sub)发布订阅来实现消息队列的,但有个缺点是消息无法持久化,如果出现网络断开,Redis宕机,消息就会被丢弃。
Stream结构是一个链表,将所有的消息都串起来,每一个消息都有一个唯一ID和对应的内容,消息是持久化的,redis重启之后,内容还在。并且能记录每一个客户端的访问位置。
每个stream都有唯一的名称,他就是Redis的key,在我们首次使用xadd指令追加消息时自动创建。
- Consumer Group: 消费组,使用XGROUP CREATE命令创建,一个消费组可以有多个消费者
- last_delivered_id: 游标,每个消费组都有一个游标,一个消费者组中任意一个消费组消费消息都会使这个游标移动
- pending_ids: 维护消费者中读取到的但没有被ack掉的消息
命令
消息队列相关命令
- XADD - 添加消息到末尾
- XTRIM - 对流进行修剪,限制长度
- XDEL - 删除消息
- XLEN - 获取流包含的元素数量,即消息长度
- XRANGE - 获取消息列表,会自动过滤已经删除的消息
- XREVRANGE - 反向获取消息列表,ID 从大到小
- XREAD - 以阻塞或非阻塞方式获取消息列表
1.XADD key ID field value [field value ...]
添加消息到末尾
key:队列名称,如果不存在就创建。
ID:消息 id,我们使用 * 表示由 redis 生成,可以自定义,但是要自己保证递增性
field value:消息内容
2.XTRIM key MAXLEN [~] count
对流进行修剪,限制长度
key :队列名称
MAXLEN :长度
count :数量
3.XDEL key ID [ID ...]
删除消息
key :队列名称
ID :消息ID
4.XLEN key
使用 XLEN 获取流包含的元素数量,即消息长度
key:队列名称
5.XRANGE key start end [COUNT count]
使用 XRANGE 获取消息列表,会自动过滤已经删除的消息
key :队列名
start :开始值, - 表示最小值
end :结束值, + 表示最大值
count :数量
6.XREVRANGE key end start [COUNT count]
使用 XREVRANGE 获取消息列表,会自动过滤已经删除的消息 与上面的区别是一个从队列左边,一个是从右边。
key :队列名
end :结束值, + 表示最大值
start :开始值, - 表示最小值
count :数量
7.XREAD [COUNT count] [BLOCK milliseconds] STREAMS key [key ...] id [id ...]
使用 XREAD 以阻塞或非阻塞方式获取消息列表,在不定义消费组的情况下,进行独立消费
count :数量
milliseconds :可选,阻塞毫秒数,没有设置就是非阻塞模式
key :队列名
id :消息 ID, 0-0表示从头开始读,$表示
消费者组相关命令
- XGROUP CREATE - 创建消费者组
- XREADGROUP GROUP - 读取消费者组中的消息
- XACK - 将消息标记为"已处理"
- XGROUP SETID - 为消费者组设置新的最后递送消息ID
- XGROUP DELCONSUMER - 删除消费者
- XGROUP DESTROY - 删除消费者组
- XPENDING - 显示待处理消息的相关信息
- XCLAIM - 转移消息的归属权
- XINFO - 查看流和消费者组的相关信息;
- XINFO GROUPS - 打印消费者组的信息;
- XINFO STREAM - 打印流信息
1.XGROUP [CREATE key groupname id-or-$] [SETID key groupname id-or-$] [DESTROY key groupname] [DELCONSUMER key groupname consumername]
使用 XGROUP CREATE 创建消费者组
key :队列名称,如果不存在就创建
groupname :组名。
$ : 表示从尾部开始消费,只接受新消息,当前 Stream 消息会全部忽略。
例如:
XGROUP CREATE mystream consumer-group-name 0-0 从头开始消费
XGROUP CREATE mystream consumer-group-name $ 从尾部开始消费
2.XREADGROUP GROUP group consumer [COUNT count] [BLOCK milliseconds] [NOACK] STREAMS key [key ...] ID [ID ...]
使用 XREADGROUP GROUP 读取消费组中的消息
group :消费组名
consumer :消费者名。
count : 读取数量。
milliseconds : 阻塞毫秒数。
key : 队列名。
ID : 消息 ID。为>表示接收新的消息
3.xack key group ID [ID ...]
消息标记确认
4.xgroup setid
如果你希望消费者组中的消费者重新处理流中的所有消息,可以设置下一个id为某一个消息id
GO操作Redis stream
使用第三方库: github.com/gomodule/redigo/redis
定义redis的初始化操作
封装操作redis stream的一系列方法
读取组内消息方法
单独读取消息方法,无消费组可使用这个
ack消息方法
删除消息方法
查询消费组的方法
业务处理流程大致如下
- 先读取消费者里 pending列表中的(表示没有被ack的消息),如果没有则读取最新消息
- 通过查询消费组信息,获取每个消费者最后的消息id,并让当前消息id跟其他消费者的最后id进行比较,如果其他消费者都已经读取过,则标记此消息删除(具体根据自己的业务处理)
- 对当前消息进行ack。
- 删除第二步中被标记为删除的消息。