redis的stream
stream 是Redis5.0引入的数据类型;支持多播的可持久化消息队列
组成:
1.消息ID:形式是整数-整数,常用timestampInMillis-sequence(毫秒的第n条消息)可由服务器自动生成也可由客户端指定;加入ID按照升序
2.消息内容: 键值对
基本使用:
1.xadd streamName 消息ID 消息内容 #返回消息ID
xadd route1 * stationname gaoxin stationid gaoxin001
xadd route1 * routename one routeid one001
xadd route1 * flow 22
xadd route1 * inflow 19
2.xrange streamname - + (顺序查询最小到最大)
xrange streamname - + (顺序查询最小到最大) count 2 (截取)
xrange streamname start_id end_id
xrevrange 逆流
3.xread
- xread count 2 streams route1 0-0 #非阻塞读
- xread block 0 count 1 streams route1 $ #阻塞读 ;读取比当前streams最大ID还大的ID信息,在当前的streams里是读取不到的,会阻塞;当这个streams插入数据后,会立马返回数据。
$ :特殊ID,该stream里面的最大ID
- xread block 0 count 1 streams route1 1607049781822-0 #阻塞读 ;读取比当前1607049781822-0还大的ID信息
block 表示命令阻塞, 0 表示阻塞的时间无限大;设置>0的整数,为阻塞的时间
消费者组
每一个stream 可以挂多个消费者组,每个消费组内有多个消费者,消费者读取消息是竞争关系
last_delivered 记录上一次消费的消息ID
命令说明:
开发58:0>xgroup create route1 cg1 0-0 #创建消费者组cg1,从头开始读
"OK"
开发58:0>xgroup create route1 cg2 $ #创建消费者组cg2,只读新进入消息
"OK"
开发58:0>xgroup create route1 cg3 0-0 #创建消费者组cg3,只读新进入消息
"OK"
开发58:0>xinfo stream route1 #查看流信息
1) "length"
2) "6"
3) "radix-tree-keys"
4) "1"
5) "radix-tree-nodes"
6) "2"
7) "groups"
8) "3"
9) "last-generated-id"
10) "1607049795921-0"
11) "first-entry"
12) 1) "1606979884337-0"
2) 1) "flow"
2) "22"
13) "last-entry"
14) 1) "1607049795921-0"
2) 1) "name"
2) "gaoxin"
#消费者消费消息
开发58:0>xreadgroup group cg1 c1 count 1 streams route1 >
1) 1) "route1"
2) 1) 1) "1606979884337-0"
2) 1) "flow"
2) "22"
开发58:0>xreadgroup group cg1 c1 count 1 streams route1 >
1) 1) "route1"
2) 1) 1) "1606979910588-0"
2) 1) "inflow"
2) "19"
#查看流的消费者组信息
开发58:0>xinfo groups route1
1) 1) "name"
2) "cg1"
3) "consumers"
4) "1"
5) "pending" #正在处理还没有应答的消息数量
6) "2"
7) "last-delivered-id"
8) "1606979910588-0" #最后读到的消息ID
2) 1) "name"
2) "cg2"
3) "consumers"
4) "0"
5) "pending"
6) "0"
7) "last-delivered-id"
8) "1607049795921-0" #cg2是从当前流最大ID开始往后读的组,前面有设置
3) 1) "name"
2) "cg3"
3) "consumers"
4) "0"
5) "pending"
6) "0"
7) "last-delivered-id"
8) "0-0" #从头开始读
#消费者ack
开发58:0>xack route1 cg1 1606979884337-0
"1"
开发58:0>xinfo consumers route1 cg1
1) 1) "name"
2) "c1"
3) "pending" #还剩一条未应答
4) "1"
5) "idle"
6) "953434"
分区:
redis不支持原生分区,如果要分区,利用多个stream,使用策略来生产消息到不同stream,达到分区效果。
遗留问题:xdel删除消息,仅仅是设置标志位,不影响总长度。测试了几次,删除后的长度会变化。
58:7002> xrange crazy - +
1) 1) "1607063653812-0"
2) 1) "num"
2) "3"
2) 1) "1607063668571-0"
2) 1) "leng"
2) "5"
3) 1) "1607063679894-0"
2) 1) "name"
2) "cra"
4) 1) "1607063787473-0"
2) 1) "property"
2) "noun"
5) 1) "1607063953418-0"
2) 1) "demand"
2) "3"
58:7002> xlen crazy
(integer) 5
58:7002> xdel crazy 1607063953418-0
(integer) 1
58:7002> xlen crazy # 长度变了
(integer) 4