DEBUG.WIKI
京东云;让 AI 进入真实业务;零售 · 物流 · 客服 · 硬件;查看方案 →
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国
Evoxt;最高 6.0GHz CPU;高频云服务器 · 免费每周备份;查看配置 →

Redis Stream 执行 XDEL 后,XPENDING 仍有消息

分清消息内容与消费组确认状态,核对业务结果后处理PEL,保留其他消费组的读取条件。

消费者用 XREADGROUP 读到消息,随后执行 XDEL,Stream 中的内容消失了,XPENDING 却仍列出那个 ID。删除消息内容和确认消费属于两个状态:XDEL 不会顺便清除消费组的待确认记录。

先看待确认 ID,再查处理结果

通过原有认证、TLS 和数据库选择连接出错的实例,保留 stream、group、consumer 和消息 ID。以下是进入 Redis 管理连接后的查询;orders、workers 是示例,应替换为实际名称。

XPENDING orders workers
XPENDING orders workers - + 10

第一条看汇总,第二条限定返回十条明细。ID 仍在待确认列表,说明该组还保留确认状态,不能据此认定业务一定没有执行。

如果读取消费者自己的历史待确认消息,已经删除内容的 ID 可能对应空 payload。遇到它时,要从业务处理记录判断消息究竟完成、失败还是丢失;空内容无法重新构造原始任务,不能直接把所有这样的 ID 当成处理成功。

XACK 清的是当前组的待确认记录

Redis 5.0 起的基础命令中,XDEL 删除 Stream 条目;XACK 则从指定消费组及对应消费者的 PEL 中移除确认记录。后者不会删除消息内容,也不会替其他组完成确认。

只有确认业务处理已成功持久化,或者已经按业务规则完成丢失消息处置,才对核实过的 ID 确认。例如:

XACK orders workers 1526569495631-0

这里的 ID 是占位示例,不能原样用于真实队列。返回值表示此次确认了多少条记录,不证明业务操作成功;返回 0 也可能是 ID 已被确认、组或键不匹配,需要结合此前查询判断。

消息还需要被其他组消费时,过早 XDEL 会让它们失去内容。修正消费流程时,把“业务完成后确认”和“达到所有消费者的保留条件后删除”分别安排,不要只追求待确认数量归零。

8.2 的组合命令仍要考虑其他组

Redis 8.2 增加 XACKDEL 与 XDELEX。前者结合当前组确认与删除;使用 KEEPREF 时,当前组完成确认,其他组的引用仍可能保留。DELREF 会移除所有组的引用,可能掩盖未完成任务,不能作为通用清理选项。

ACKED 用于约束删除条件,考虑其他组是否已经读取并确认。采用前核对服务端与客户端支持、全部消费组的处理约定,在隔离 stream 验证,不把这些参数复制给不支持它们的旧版本。

PEL 记录和 Stream 存储占用也不同。删除条目不保证内存按条立即下降,待确认 ID 的存在更不足以单独证明内存泄漏。处理后复查目标组、具体 ID、业务结果与后续消费,再单独分析内存;不要把确认几条消息写成所有 OOM 的解决办法。