vault backup: 2026-06-08 23:08:57

This commit is contained in:
hhs
2026-06-08 23:08:57 +08:00
parent d67831afe0
commit 51de196713
136 changed files with 26069 additions and 344 deletions
+24 -2
View File
@@ -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