vault backup: 2026-06-08 23:08:57
This commit is contained in:
+24
-2
@@ -163,6 +163,12 @@ sequenceDiagram
|
||||
> [!question] 消息是如何分配给消费者的?
|
||||
> Redis 采用**轮询分配**(round-robin):新消息到达时,依次分配给组内活跃的消费者。注意不是负载均衡——如果某个消费者处理慢,它积压的 pending 消息不会自动转移给其他消费者,需要通过 XCLAIM 手动认领。
|
||||
|
||||
> [!tip] NOACK 模式——高吞吐场景的取舍
|
||||
> `XREADGROUP` 支持 `NOACK` 选项,消息读取后**跳过 PEL,直接视为已消费**。适用于对可靠性要求不高但吞吐要求极高的场景(如实时指标采样)。代价是消费者崩溃时消息会永久丢失。
|
||||
> ```bash
|
||||
> XREADGROUP GROUP mygroup consumer1 NOACK COUNT 10 BLOCK 5000 STREAMS mystream >
|
||||
> ```
|
||||
|
||||
### XINFO —— 运维监控利器
|
||||
|
||||
排查 Stream 问题时,`XINFO` 是你的第一选择:
|
||||
@@ -311,7 +317,7 @@ func (c *StreamConsumer) ClaimAbandoned(ctx context.Context, minIdle time.Durati
|
||||
pendings, err := c.rdb.XPendingExt(ctx, &redis.XPendingExtArgs{
|
||||
Stream: c.stream,
|
||||
Group: c.group,
|
||||
Idle: minIdle,
|
||||
MinIdle: minIdle,
|
||||
Start: "-",
|
||||
End: "+",
|
||||
Count: 100,
|
||||
@@ -386,6 +392,19 @@ XADD mystream MINID 1685000000000-0 * field value
|
||||
XADD mystream MINID ~ 1685000000000-0 * field value # 近似模式
|
||||
```
|
||||
|
||||
### XDEL —— 删除单条消息
|
||||
|
||||
```bash
|
||||
# 删除指定 ID 的消息
|
||||
XDEL mystream 1685000000000-0
|
||||
|
||||
# 批量删除
|
||||
XDEL mystream 1685000000000-0 1685000000000-1
|
||||
```
|
||||
|
||||
> [!warning] XDEL 不会清除 PEL 引用
|
||||
> 与 `MAXLEN`/`MINID` 一样,`XDEL` 删除的是 Stream 中的原始消息,但 Pending Entry List 中的引用仍然存在。被删除的消息 ID 在 `XPENDING` 中仍可见,`XCLAIM` 尝试读取时会返回 nil。
|
||||
|
||||
### XTRIM —— 手动裁剪
|
||||
|
||||
```bash
|
||||
@@ -416,6 +435,9 @@ XTRIM mystream MINID 1685000000000-0
|
||||
> - **实时推送、允许丢消息**:Pub/Sub 更简单直接
|
||||
> - **海量事件流、需要精确一次语义**:Kafka 不可替代
|
||||
|
||||
> [!warning] Redis Cluster 模式下的 Stream
|
||||
> 在 Redis Cluster 中,一个 Stream 被分配到**单个 slot**,所有写入和读取都路由到同一节点,**无法水平分片**。Consumer Group 的所有操作(XREADGROUP、XACK、XPENDING)也必须在同一节点完成。如果单个 Stream 成为热点,考虑将其拆分为多个 Stream(如 `orders:0`、`orders:1`……)并使用客户端负载均衡。
|
||||
|
||||
## 七、死信队列(Dead Letter Queue)
|
||||
|
||||
当某条消息被重试 N 次仍然失败时,继续重试没有意义。此时应将其移入**死信队列**,等待人工介入或补偿处理。
|
||||
@@ -438,7 +460,7 @@ func (c *StreamConsumer) ProcessPendingWithDLQ(ctx context.Context) {
|
||||
}).Result()
|
||||
|
||||
for _, p := range pendings {
|
||||
if p.RetryCount >= maxRetries {
|
||||
if p.TimesDelivered >= maxRetries {
|
||||
// 超过重试次数 → 写入死信 Stream
|
||||
c.moveToDLQ(ctx, p.ID)
|
||||
continue
|
||||
|
||||
Reference in New Issue
Block a user