代码 Redis 8.2 的 XACKDEL/XDELEX:PEL 引用怎么删,BITOP 又多了四个运算符

2026-09-24 21:14:17

Redis 8.2 的 XACKDEL/XDELEX:PEL 引用怎么删,BITOP 又多了四个运算符

来源:Redis 8.2 streams and bitmap enhancements(2025-08-12),Redis 8.2 GA 发布于 2025-08-04。

背景:XACK 和 XDEL 是两件事

消费者组把投递给消费者的条目记在 PEL(Pending Entries List)里。XACK 只清 PEL,XDEL 只删流里的条目,两条命令互不知情。于是常见写法 XACK + XDEL 的组合里,XDEL 执行后条目在 Stream 中没了,但各个消费者组 PEL 中指向该 ID 的引用还挂着,变成悬空引用,只能等超时或另外清理。

8.2 新增的 XACKDELXDELEX,以及给 XADD/XTRIM 加的三个选项,就是把「删条目的同时,引用怎么办」这件事显式化。

KEEPREF / DELREF / ACKED 的语义差异

三个选项在所有相关命令里含义一致:

  • KEEPREF:从 Stream 删条目,但保留所有消费者组 PEL 中已有的引用。行为和老的 XDEL 一致。
  • DELREF:删条目,同时清掉所有消费者组 PEL 中的引用,不留痕迹。注意边界:如果某个 ID 已经不在 Stream 里、但 PEL 里还有悬空引用,这些引用同样会被清除——它按引用清理,不要求条目还在。
  • ACKED:只删除那些在所有消费者组中都已被读取并确认的条目。只要还有任何一个组没读过或没 ack,就不删。

XACKDEL

XACKDELXACKXDEL 合并成一步:先在指定消费者组里确认条目,再按条件从 Stream 删除对应条目。

XACKDEL key group [KEEPREF | DELREF | ACKED] ID [ID ...]

这里有个容易看错的地方:ack 是打在指定的那个 group 上的,但删除条件里的 ACKED 判断的是所有消费者组的确认状态。多组消费同一个 Stream 时,这一点决定条目会不会被真正删掉。

Redis 文档的建议是:用 XACKDEL ... ACKED 取代 XACK + XDEL。后者会留下悬空引用,前者不会。

XDELEX

XDELEXXDEL 的扩展,接受同样的三个选项,用来控制「什么时候删条目、什么时候清 PEL 引用」。

XDELEX key [KEEPREF | DELREF | ACKED] ID [ID ...]

KEEPREF 下行为与 XDEL 接近。XDELEX ... ACKED 则只删那些在所有消费者组中都被读取并确认的条目——适合在巡检或后台任务里做「安全回收」,把无人认领的条目留着,避免误删还在处理中的消息。

XADD 与 XTRIM 也带上了这三个选项

XADDXTRIM 本身也会删条目(MAXLEN/MINID 截断、近似模式清理),所以 8.2 给它们都加上了 [KEEPREF | DELREF | ACKED]

KEEPREFXADDXTRIM 的默认值,也就是原有行为不变,升级不会静默改变语义。要清引用必须显式写 DELREFACKED

踩坑点

  • 近似模式下的 DELREF/ACKED 不生效(8.2.7 修复,#14623):XTRIM/XADD~ 近似裁剪时,DELREF/ACKED 策略不会真的删除条目。在 8.2.0–8.2.6 上依赖这个行为会出问题。
  • XGROUP DESTROY 之后的行为(#14552,已修复):在组被销毁后使用 XDELEX ... ACKED 会得到不正确的结果。如果业务里会动态销毁消费者组,注意版本。
  • 默认是 KEEPREF:升级到 8.2 后旧代码行为不变,但如果原本指望「删了就干净」,得把参数补上。反过来,从 ACKED 换成 KEEPREF 时,PEL 里的悬空引用会重新出现。
  • DELREF 连悬空引用一起清:这是清理历史脏数据的便利,也意味着它不检查条目是否真实存在,调用前确认 ID 来源可靠。

BITOP:新增四个运算符

8.2 之前 BITOP 只有 ANDORXORNOT。8.2 增加:

  • BITOP DIFF destkey X [Y1 Y2 ...]:某位在 X 中为 1、且在 Y1、Y2… 中都不为 1 时置 1。
  • BITOP DIFF1 destkey X [Y1 Y2 ...]:某位在 Y1、Y2… 中至少一个为 1、但在 X 中不为 1 时置 1。方向与 DIFF 相反。
  • BITOP ANDOR destkey X [Y1 Y2 ...]:某位在 X 中为 1、且在 Y1、Y2… 中至少一个为 1 时置 1。
  • BITOP ONE destkey X1 [X2 X3 ...]:某位在 X1、X2… 中恰好一个为 1 时置 1。

这四个操作符把之前需要在客户端多次取位图再拼结果的计算下推到 Redis 侧,适合位图去重、多集合差集、多条件位掩码这类场景。

8.2 其它变化

  • 新命令 CLUSTER SLOT-STATS:按 slot 输出使用指标,包括 key 数量、CPU 时间、网络 I/O。
  • VSIM 新增 IN 运算符,用于过滤。
  • 新增 SVS-VAMANA 向量索引类型,带压缩。
  • Keyspace 通知新增 OVERWRITTEN(值被完整覆盖)和 TYPE_CHANGED(键类型变更)两个事件。
  • 统一的键值对象(kvobj)存储:短字符串内存降低 25%–37%,JSON 数值最高降低 67%。
  • I/O 多线程吞吐提升最高 49%。

参考

复制全文 生成海报 Redis Streams 命令 缓存

推荐文章

程序员茄子在线接单