doc: 阅读redis xinfo文档

This commit is contained in:
asahi
2025-09-17 10:43:14 +08:00
parent 33c29d2d88
commit fe9e3ebbe7

View File

@@ -109,6 +109,11 @@
- [XCLAIM](#xclaim)
- [JUSTID option](#justid-option)
- [Automatic claiming](#automatic-claiming)
- [Claiming and the delivery counter](#claiming-and-the-delivery-counter)
- [working with multiple consumer groups](#working-with-multiple-consumer-groups)
- [Enhanced deletion control in Redis 8.2](#enhanced-deletion-control-in-redis-82)
- [Stream Observability](#stream-observability)
- [Difference with kafka partitions](#difference-with-kafka-partitions)
# redis
@@ -1952,4 +1957,111 @@ XAUTOCLAIM <key> <group> <consumer> <min-idle-time> <start> [COUNT count] [JUSTI
当`XAUTOCLAIM`返回“0-0”作为cursor时代表其到达了`end of the consumer group pending entries list`。其并不代表没有新的idle pending messages可以重新从begining of the stream来调用`XAUTOCLAIM`。
##### Claiming and the delivery counter
通过`XPENDING`命令输出的counter代表该message的被传递次数该counter在两种场景下会增加
- when a message is successfully claimed via `XCLAIM`
- when a `XREADGROUP` call is used in order to access the history of pending messages
当存在failure时message可能会被传递多次但是message最终会被处理并ack。但是在处理特定的消息时可能会在处理逻辑中抛出异常在该类场景下consumer会持续的在处理该消息时抛出异常。故而可以通过delivery counter来探知那些不可处理的message。`一旦delivery counter到达给定的值时可以将该消息发送给另一个stream并且向系统的管理员发送notification。`这就是redis stream实现`dead letter`的基础。
##### working with multiple consumer groups
redis stream可以关联多个consumer groups每个entries都会被传递给每个consumer group。在consumer group内每个consumer instance处理一部分entries。
当consumer对message进行处理时其会使用`XACK`命令来对message进行确认`并且从consumer group的Pending Entries ListPEL中移除该entry reference`。但是,`被ack的message仍然保存在stream中`且consumer group A中对message的ack并不会影响consumer group B的PELgroup A在对message进行ack后message仍然位于group B的PEL中直到group B中的consumer对message进行ack此时message才从group B的PEL中被移除。
通常来说如果想要从stream中删除entries必须要等到所有的consumer groups都对entries进行了ack应用需要实现复杂的逻辑。
###### Enhanced deletion control in Redis 8.2
从redis 8.2开始,一些命令为`entries在多个consumer groups间的处理`提供了增强控制:
- `XADD`支持KEEPREF, DELREF, ACKED模式
- `XTRIM`同样支持KEEPREF, DELREF, ACKED选项
如下选项控制consumer group references是如何被处理的
- `KEEPREF`(默认) Preserves existing references to entries in all consumer groups' PELs
- `DELREF`: Removes all references to entries from consumer groups' PELs, effectively cleaning up all traces of the messages
- `ACKED`: Only processes entries that have been acked by all consumer groups
`ACKED` mode对于`coordinating deletion across multiple consumer groups`的复杂逻辑十分有用确认entires在所有consumer groups在完成对其的处理后才移除。
##### Stream Observability
缺乏可观测性的消息系统将十分难以使用,一个透明的消息系统需要令如下信息可观测:
- who is consuming messages
- what messages are pending
- the set of consumer groups active in a given stream
在前面章节中,已经介绍了`XPENDINGS`命令,通过其可以观测处于`处理中`状态的消息并且能够获取消息的idle time和number of deliveries。
`XINFO`命令和sub-commands一起使用可以用于获取stream和consumer group相关的信息。
`XINFO`命令的使用示例如下:
```redis-cli
> XINFO STREAM race:italy
1) "length"
2) (integer) 5
3) "radix-tree-keys"
4) (integer) 1
5) "radix-tree-nodes"
6) (integer) 2
7) "last-generated-id"
8) "1692632678249-0"
9) "groups"
10) (integer) 1
11) "first-entry"
12) 1) "1692632639151-0"
2) 1) "rider"
2) "Castilla"
13) "last-entry"
14) 1) "1692632678249-0"
2) 1) "rider"
2) "Norem"
```
上述示例中,通过`XINFO`命令获取了stream本身的信息输出展示了stream内部的编码方式并且记录了stream中的第一条消息和最后一条消息。
如果想要获取和stream相关的consumer group消息参照如下示例
```redis-cli
> XINFO GROUPS race:italy
1) 1) "name"
2) "italy_riders"
3) "consumers"
4) (integer) 3
5) "pending"
6) (integer) 2
7) "last-delivered-id"
8) "1692632662819-0"
```
如果想要查看consumer group中注册的consumer实例可以通过`XINFO CONSUMERS`命令来进行查看:
```redis-cli
> XINFO CONSUMERS race:italy italy_riders
1) 1) "name"
2) "Alice"
3) "pending"
4) (integer) 1
5) "idle"
6) (integer) 177546
2) 1) "name"
2) "Bob"
3) "pending"
4) (integer) 0
5) "idle"
6) (integer) 424686
3) 1) "name"
2) "Lora"
3) "pending"
4) (integer) 1
5) "idle"
6) (integer) 72241
```
##### Difference with kafka partitions
Redis stream中的consumer group可能在某些方面类似于kafka中基于分区的consumer groups但是仍然存在较大差别。
在redis strema中`partition`这一概念是逻辑的实际上stream所有的messages都存在相同的key中。故而redis stream中consumer instance并不从实际的partition中读取信息也不涉及partition在consumer间的分配。
> 例如如果consumer C3在某个时刻fail permanentlyredis在所有新消息到达时都会传递给C1和C2将好像redis stream只存在2个逻辑分区。
类似的如果某个consumer处理消息比其他consumers都快那么该consumer将在单位时间内按比例收到更多的消息。Redis会追踪所有尚未被ack的消息并且记录哪条消息被哪个consumer接收`the ID of the first message never delivered to any consumer`也会被redis记录。
在redis Stream中
- 如果redis stream的数量和consumer的数量都为1那么消息将是按照顺序被处理的
- 如果stream的数量为1consumer的数量为n那么可以将负载均衡给n个consumers但是在这种情况下消息的消费可能是无序的
- 当使用n个stream和n个consumers时一个consumer只用于处理所有streams中的一部分可以将`1 stream->1 consumer`拓展到`n stream->n consuimer`