hztech Redis Stream Commands 命令学习-2 XREAD
Listening for new items with XREAD
When we do not want to access items by a range in a stream, usually what we want instead is to subscribe to new items arriving to the stream. This concept may appear related to Redis Pub/Sub, where you subscribe to a channel, or to Redis blocking lists, where you wait for a key to get new elements to fetch, but there are fundamental differences in the way you consume a stream:
- A stream can have multiple clients (consumers) waiting for data. Every new item, by default, will be delivered to every consumer that is waiting for data in a given stream. This behavior is different than blocking lists, where each consumer will get a different element. However, the ability to fan out to multiple consumers is similar to Pub/Sub.
- While in Pub/Sub messages are fire and forget and are never stored anyway, and while when using blocking lists, when a message is received by the client it is popped (effectively removed) from the list, streams work in a fundamentally different way. All the messages are appended in the stream indefinitely (unless the user explicitly asks to delete entries): different consumers will know what is a new message from its point of view by remembering the ID of the last message received.
- Streams Consumer Groups provide a level of control that Pub/Sub or blocking lists cannot achieve, with different groups for the same stream, explicit acknowledgment of processed items, ability to inspect the pending items, claiming of unprocessed messages, and coherent history visibility for each single client, that is only able to see its private past history of messages.
The command that provides the ability to listen for new messages arriving into a stream is called XREAD
. It's a bit more complex than XRANGE
, so we'll start showing simple forms, and later the whole command layout will be provided.
> XREAD COUNT 2 STREAMS mystream 0
1) 1) "mystream"
2) 1) 1) 1519073278252-0
2) 1) "foo"
2) "value_1"
2) 1) 1519073279157-0
2) 1) "foo"
2) "value_2"
The above is the non-blocking form of XREAD
. Note that the COUNT option is not mandatory, in fact the only mandatory option of the command is the STREAMS option, that specifies a list of keys together with the corresponding maximum ID already seen for each stream by the calling consumer, so that the command will provide the client only with messages with an ID greater than the one we specified.
In the above command we wrote STREAMS mystream 0
so we want all the messages in the Stream mystream
having an ID greater than 0-0
. As you can see in the example above, the command returns the key name, because actually it is possible to call this command with more than one key to read from different streams at the same time. I could write, for instance: STREAMS mystream otherstream 0 0
. Note how after the STREAMS option we need to provide the key names, and later the IDs. For this reason, the STREAMS option must always be the last option. Any other options must come before the STREAMS option.
从标题可以看出,XREAD 可以对stream中的ITEMS 进行监听,这是区别说XRANGE的最大特点
这个命令与redis 的publish /subscriber 类似,但是有着显著的特点,
127.0.0.1:6386> publish c1 helloworld (integer) 1 127.0.0.1:6386> nihao (error) ERR unknown command `nihao`, with args beginning with: 127.0.0.1:6386> publish c1 nihao (integer) 1 127.0.0.1:6386> publish c1 消息 (integer) 1 127.0.0.1:6386>
[root@machine138 ~]# /opt/module/redis-stack/bin/redis-cli -p 6386 127.0.0.1:6386> subscribe c1 Reading messages... (press Ctrl-C to quit) 1) "subscribe" 2) "c1" 3) (integer) 1 1) "message" 2) "c1" 3) "helloworld" 1) "message" 2) "c1" 3) "nihao" 1) "message" 2) "c1" 3) "\xe6\xb6\x88\xe6\x81\xaf"
上面是简单的publish 和 subscribe 的效果展示 1、一个stream可以同时被 多个客户端(consumer)监听,有新消息可以分别收到一份,这中群发(fan out)与pub/sub 相似 2、pub/sub对消息接收后就没有了,消息不会存储,但是stream 中的消息会被 存储,并有一个唯一的ID ,每个消费者都可以标记自已对消息的处理状态,是否读取,处理到哪条消息等 3、stream 还一个比pub/sub 及 block list 更强大的功能叫做 cosumber group (消费者组),同一个stream 可以对应多个组,每个组的消息是互相隔离的,在组内可以对消息进行读取,处理, 待确认,确认,可以对历史消息且仅能对自己的消息进行处理。 XREAD 命令参数格式如下: XREAD [COUNT count] [BLOCK milliseconds] STREAMS key [key ...] id [id ...] [COUNT count]:可选 COUNT n ,n代表读取消息的条数 [BLOCK milliseconds] 可选 ,不选择时功能与XRANGE相同, BLOCK m ,m代表毫秒数 就是没有消息时阻塞等待多少毫秒 STREAMS key 必选参数 key 可以是多个,就是同时读取多个stream 的消息,从哪条消息开始,取决于后面的参数 id id 必选参数 可多个 ,数量 与上面的key 数量对应,读取大于此ID的消息, 格式为 <millSecondTime>-<sequence> 可以简单传入 0 redis 会自动按 0-0处理。 另外,在指定参数BLOCK millseconds 时ID 还有一个特别的表示:就是 $表示只获取最新的消息,就是从block 监听开始之后xadd的第一个消息 多个消息时遵循 FIFO
返回值 :这个命令返回值 为nil 或 如下格式
1) 1) "s1" 2) 1) 1) "1678606952119-0" 2) 1) "k1" 2) "v1" 3) "k2" 4) "v2" 5) "k3" 6) "v3" 7) "k4" 8) "v4" 9) "k5" 10) "v5" 11) "k6" 12) "v6" 2) 1) "1678607225979-0" 2) 1) "k1" 2) "v1" 3) "k2" 4) "v2" 5) "k3" 6) "v3" 7) "k4" 8) "v4" 9) "k5" 10) "v5" 11) "k6" 12) "v6" 3) 1) "1678607270304-0" 2) 1) "k1" 2) "v1" 4) 1) "1678607274575-0" 2) 1) "k2" 2) "v2" 5) 1) "1678607277734-0" 2) 1) "k3" 2) "v3" 6) 1) "1678607281420-0" 2) 1) "k4" 2) "v4" 7) 1) "1678607366038-0" 2) 1) "k5" 2) "v5" 8) 1) "1678607370284-0" 2) 1) "k6" 2) "v6"
未完待续 。。。xreadgroup