doc: 阅读redis stream document

This commit is contained in:
asahi
2025-09-17 14:32:35 +08:00
parent fe9e3ebbe7
commit 58fa0617ce

View File

@@ -114,6 +114,12 @@
- [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)
- [Capped Streams](#capped-streams)
- [XADD with MAXLEN](#xadd-with-maxlen)
- [XTRIM](#xtrim)
- [Trimming with consumer group Awareness](#trimming-with-consumer-group-awareness)
- [Special IDs in streams API](#special-ids-in-streams-api)
- [Persistence, replication and message safety](#persistence-replication-and-message-safety)
# redis
@@ -2065,3 +2071,83 @@ Redis stream中的consumer group可能在某些方面类似于kafka中基于分
- 如果stream的数量为1consumer的数量为n那么可以将负载均衡给n个consumers但是在这种情况下消息的消费可能是无序的
- 当使用n个stream和n个consumers时一个consumer只用于处理所有streams中的一部分可以将`1 stream->1 consumer`拓展到`n stream->n consuimer`
#### Capped Streams
在许多应用中并不想在stream中永久存储data。有时需要限制stream中entries的最大数量。
##### XADD with MAXLEN
redis stream对上述特性提供了支持在使用`XADD`命令时,支持指定`MAXLEN`选项,示例如下所示:
```redis-cli
> XADD race:italy MAXLEN 2 * rider Jones
"1692633189161-0"
> XADD race:italy MAXLEN 2 * rider Wood
"1692633198206-0"
> XADD race:italy MAXLEN 2 * rider Henshaw
"1692633208557-0"
> XLEN race:italy
(integer) 2
> XRANGE race:italy - +
1) 1) "1692633198206-0"
2) 1) "rider"
2) "Wood"
2) 1) "1692633208557-0"
2) 1) "rider"
2) "Henshaw"
```
当使用`MAXLEN`选项时如果达到了指定长度那么old entries将自动被淘汰从而确保stream处于恒定的大小。
`trimming with MAXLEN`的开销在部分场景下可能会变得很大:为了内存效率stream由radix-tree结构表示。radix-tree由macro nodes组成单个macro node中包含多个elements对单个macro node的修改并不高效。
故而,支持按照如下形式来使用`XADD`命令,并支持`MAXLEN`选项:
```redis-cli
XADD race:italy MAXLEN ~ 1000 * ... entry fields here ...
```
在上述示例中,在`MAXLEN`和`count`之间指定了`~`,代表`并不需要将长度上限严格限制为1000`。该长度可以是`1000`,可以是`1010`只保证该长度比1000大。在指定了`~`后只有当允许移除整个节点时trimming操作才会被实际执行。指定`~`能够让`MAXLEN`操作更加高效。
##### XTRIM
同样的redis还支持`XTRIM`命令,其执行和`MAXLEN`类似:
```redis-cli
> XTRIM race:italy MAXLEN 10
(integer) 0
> XTRIM mystream MAXLEN ~ 10
(integer) 0
```
除此之外,`XTRIM`命令还支持不同的trimming strategies
- `MINID`:该trimming strategy支持对`entries with IDs lower than the on specified`进行淘汰
##### Trimming with consumer group Awareness
从redis 8.2开始,`XADD with trimming options`和`XTRIM`命令都支持`enhanced control over how trimming interacts with consumer groups`,其支持`KEEPREF, DELREF, ACKED`三个选项:
```redis-cli
XADD mystream KEEPREF MAXLEN 1000 * field value
XTRIM mystream ACKED MAXLEN 1000
```
- `KEEPREF`(default): Trim entries according to the strategy but preserves references references in consumer groups' PELs
- `DELREF`: Trims entries and removes all references from consumer groups' PELs
- `ACKED`: Only Trims entries that have been acknowledged by all consumer groups
`ACKED`模式在多个consumer groups之间维护数据完整性十分有用其能够保证entries只有`当被所有的consumer groups都处理完成之后`才会被移除
#### Special IDs in streams API
在redis API中存在部分`Special IDs`
- `-, +`: 这两个特殊ID分别代表`the smallest ID possible`和`the greatest ID possible`
- `$`: 该ID代表`stream中已经存在的最大ID`。在使用`XREADGROUP`命令时如果只希望读取new entries可以使用该`special ID`。同样的可以将consumer group的`last delivered ID`设置为`$`,从而`just deliver new entries to consumers in the group`。
- `>`: 该ID代表`last delivered ID of a consumer group`该ID的适用范围仅位于同一`consumer group`内并且该ID仅在`XREADGROUP`命令中使用,代表`we want only entries that were never delivered to other consumers so far`。
- `*`: 该ID仅在`XADD`命令中被使用代表为new entry自动选中ID
#### Persistence, replication and message safety
stream和redis中的其他数据结构一样`is asynchronously replicated to replicas`,并且持久化到`RDB`和`AOF`文件中。并且,`consumer group的full state也会被传播到AOF, RDB, replcias中`。
故而,如果`message is pending in the master, also the replica will have the same information`。并且当重启后AOF也会恢复consumer group的状态。
redis streams和consumer groups将会被持久化并且`replicated using the Redis default replication`
- 如果消息的持久化十分重要,那么`AOF必须使用strong fsync policy`
- `redis asynchronously replication`并不能保证`xadd`/`consumer group state changes`能被同步到replica
- 当发生failover故障转移指哨兵或集群模式下主节点发生故障replica节点被升级为主节点可能主节点的变化尚未被同步到replica此时failover将会产生data missing
- `WAIT命令可以强制使changes被传播给replicas`,该命令仅会降低数据丢失的可能,但是并无法完全避免数据的丢失。
- 在发生故障转移时redis仅会执行`best effort check`,从而转移到`replica which is the most updated`在某些失败场景下转移到的replica仍然可能缺失部分数据