*Redis XACKDEL 命令
XACKDEL 用于同时确认(acknowledge)并删除 Stream 中的指定条目,实现对消费组 PEL 和 Stream 数据的原子清理。
*语法
XACKDEL key group [KEEPREF | DELREF | ACKED] IDS numids id [id ...]
*参数说明
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| key | String | 是 | Stream 键名 |
| group | String | 是 | 消费组名称 |
| KEEPREF / DELREF / ACKED | Flag | 否 | 引用处理策略(默认 KEEPREF) |
| IDS numids | Integer | 是 | 后续 ID 的数量 |
| id [id ...] | String | 是 | 要确认并删除的一个或多个条目 ID |
策略说明: - KEEPREF(默认):确认条目并删除,但保留其他消费组 PEL 中的引用 - DELREF:确认条目并删除,同时清理所有消费组 PEL 中的引用 - ACKED:仅删除已被所有消费组确认过的条目
*返回值
- Array:对每个 ID 返回状态码
1:条目已确认并从 Stream 中删除2:条目已确认但未删除(仍有引用或 ACKED 模式)-1:Stream 中不存在该 ID
- Array (-1):当 key 不存在时,对每个 ID 返回
-1 - Error:参数错误、类型错误等
*时间复杂度
O(1) 对每个处理的条目 ID。
*示例
*基本用法(KEEPREF 默认)
> XADD mystream * field1 value1
"1755870377536-0"
> XGROUP CREATE mystream mygroup 0
OK
> XREADGROUP GROUP mygroup consumer1 COUNT 1 STREAMS mystream >
1) 1) "mystream"
2) 1) 1) "1755870377536-0"
2) 1) "field1"
2) "value1"
> XACKDEL mystream mygroup IDS 1 1755870377536-0
1) (integer) 1
> XRANGE mystream - +
(empty array)
*使用 DELREF 清理所有引用
> XADD mystream * msg hello
"1755870400000-0"
> XGROUP CREATE mystream group1 0
OK
> XGROUP CREATE mystream group2 0
OK
> XREADGROUP GROUP group1 c1 COUNT 1 STREAMS mystream >
...
> XREADGROUP GROUP group2 c2 COUNT 1 STREAMS mystream >
...
> XACKDEL mystream group1 DELREF IDS 1 1755870400000-0
1) (integer) 1
> XPENDING mystream group2
1) (integer) 0
...
*使用 ACKED 安全删除
> XADD mystream * data test
"1755870500000-0"
> XGROUP CREATE mystream g1 0
OK
> XREADGROUP GROUP g1 c1 COUNT 1 STREAMS mystream >
...
> XACKDEL mystream g1 ACKED IDS 1 1755870500000-0
1) (integer) 2
> XACK mystream g1 1755870500000-0
(integer) 0
> XACKDEL mystream g1 ACKED IDS 1 1755870500000-0
1) (integer) 1
*常见错误
| 错误 | 原因 | 解决 |
|---|---|---|
| ERR wrong number of arguments | IDS 块格式错误或缺少 ID | 检查 IDS numids id... 格式 |
| WRONGTYPE | key 不是 Stream 类型 | 确认 key 的数据类型 |
| NOGROUP | 指定的消费组不存在 | 先使用 XGROUP CREATE 创建 |
| -1 | 条目 ID 在 Stream 中不存在 | 确认 ID 正确性 |
*最佳实践
- 多消费组场景下,优先使用
ACKED策略替代独立的 XACK + XDEL,简化应用逻辑 DELREF适合在确认后立即彻底清理的场景,避免 dangling PEL entries- 批量操作时用
IDS numids id1 id2 ...语法减少 RTT - 建议在消费者处理成功后立即调用,避免 PEL 堆积
*FAQ
Q1: XACKDEL 和先 XACK 再 XDEL 有什么区别? A: XACKDEL 是原子操作,避免 XACK 成功但 XDEL 失败的中间状态。同时提供 KEEPREF/DELREF/ACKED 三种策略,更灵活。
Q2: KEEPREF 和 DELREF 在实际应用中有何不同? A: KEEPREF 只删除 Stream 数据但保留其他组的 PEL 引用,适合各组独立管理消息生命周期的场景;DELREF 会强制清理所有引用,适合确定消息可被全局删除的场景。
Q3: 为什么 ACKED 模式下返回 2? A: 返回 2 表示条目已被确认但尚未被所有消费组确认,因此未被删除。当所有组都确认后,再次执行才会返回 1 并删除。