*Redis XDELEX 命令

XDELEX 用于从 Stream 中删除一个或多个条目,并提供对消费组 PEL 引用的精细化控制。


*语法

XDELEX key [KEEPREF | DELREF | ACKED] IDS numids id [id ...]

*参数说明

参数 类型 必填 说明
key String Stream 键名
KEEPREF / DELREF / ACKED Flag 引用处理策略(默认 KEEPREF)
IDS numids Integer 后续 ID 的数量
id [id ...] String 要删除的一个或多个条目 ID

策略说明: - KEEPREF(默认):删除 Stream 中的条目,保留消费组 PEL 中的引用(行为同 XDEL) - DELREF:删除条目并清理所有消费组 PEL 中的引用,彻底消除 dangling entries - ACKED:仅删除已被所有消费组确认过的条目


*返回值

  • Array:对每个 ID 返回状态码
    • 1:条目已从 Stream 中删除
    • 2:条目未删除(ACKED 模式下仍有未确认引用或无消费组)
    • -1:Stream 中不存在该 ID 或 key 不存在
  • Error:参数错误、类型错误等

*时间复杂度

O(1) 对每个删除的条目,与 Stream 大小无关。


*示例

*基本删除(KEEPREF 默认)

> XADD mystream * field1 value1
"1755870377536-0"
> XADD mystream * field2 value2
"1755870387045-0"
> XDELEX mystream IDS 1 1755870377536-0
1) (integer) 1
> XRANGE mystream - +
1) 1) "1755870387045-0"
   2) 1) "field2"
      2) "value2"

*使用 DELREF 彻底清理

> XADD mystream * msg hello
"1755870400000-0"
> XGROUP CREATE mystream mygroup 0
OK
> XREADGROUP GROUP mygroup c1 COUNT 1 STREAMS mystream >
...
> XDELEX mystream DELREF IDS 1 1755870400000-0
1) (integer) 1
> XPENDING mystream mygroup
1) (integer) 0
...

*ACKED 安全删除

> XADD mystream * data test
"1755870500000-0"
> XGROUP CREATE mystream g1 0
OK
> XREADGROUP GROUP g1 c1 COUNT 1 STREAMS mystream >
...
> XDELEX mystream ACKED IDS 1 1755870500000-0
1) (integer) 2
> XACK mystream g1 1755870500000-0
(integer) 1
> XDELEX mystream ACKED IDS 1 1755870500000-0
1) (integer) 1

*常见错误

错误 原因 解决
ERR wrong number of arguments IDS 块格式错误或缺少 ID 检查 IDS numids id... 格式
WRONGTYPE key 不是 Stream 类型 确认 key 的数据类型
-1 条目 ID 不存在或 key 不存在 确认 ID 和 key 正确性

*最佳实践

  • 无消费组的简单场景下,XDELEX 与 XDEL 行为一致
  • 使用消费组时,优先用 ACKED 策略确保消息已被所有组处理后再删除
  • DELREF 适合手动清理 dangling PEL entries,或 GDPR 等合规删除场景
  • 批量删除时使用 IDS numids id1 id2 ... 减少网络往返

*FAQ

Q1: XDELEX 和 XDEL 有什么区别? A: XDELEX 是 XDEL 的扩展,增加了 KEEPREF/DELREF/ACKED 策略,可精细化控制消费组 PEL 引用的清理行为。

Q2: DELREF 能删除不存在的条目吗? A: 如果条目 ID 不在 Stream 中但 PEL 中有 dangling 引用,DELREF 仍会清理这些引用并返回成功。

Q3: ACKED 模式下返回 2 是什么意思? A: 表示条目存在但未被所有消费组确认,因此未被删除。需要所有组确认后才能安全删除。