登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  数据库 >  Redis

Redis XPENDING 怎样读取消费者组的空闲消息

来源:17golang原创

时间:2026-10-26 21:02:44 229浏览 收藏

Redis Streams 消费者组里的消息被某个消费者读走、但还没有执行 XACK 时,会留在 Pending Entries List(PEL)中。想找出“已经很久没人处理”的消息,先用 XPENDING key group 看全组摘要,再用详情形式配合 IDLE、ID 范围和 count 读取具体条目。

官方地址:https://redis.io/docs/latest/commands/xpending/

最实用的查询是 XPENDING mystream workers IDLE 60000 - + 20:它只观察空闲时间达到 60000 毫秒的 pending 消息,最多返回 20 条。返回的四个字段依次是消息 ID、当前消费者、空闲毫秒数和投递次数。

先用摘要确认 PEL 是否有积压

排查时不要一上来就拉取全部消息。只传 Stream 键和消费者组名,XPENDING 返回的是组级概览:pending 总数、最小消息 ID、最大消息 ID,以及每个拥有待确认消息的消费者和对应数量。这个结果适合先判断积压是否存在、集中在哪个消费者。

# 先看 workers 组是否有未确认消息,以及积压归属
redis-cli XPENDING mystream workers

# 典型摘要:总数、最小 ID、最大 ID、消费者及其 pending 数量
# 1) (integer) 3
# 2) "1710000000000-0"
# 3) "1710000001200-0"
# 4) 1) 1) "consumer-a"
#       2) "2"
#    2) 1) "consumer-b"
#       2) "1"

摘要中的消费者数量不是消费者的在线状态,也不是消息正文。它只表示当前 PEL 中每个消费者名下的待确认数量;如果总数为 0,后面的最小/最大 ID 和消费者列表也就没有可供排查的 pending 条目。

Stream、消费者组、PEL 与 XPENDING 摘要和详情字段的静态关系图
图1:结构说明图,展示 XPENDING 摘要与详情返回对象的关系,不是 Redis 控制台截图。

用详情形式读取消息级字段

在命令后补上起始 ID、结束 ID和返回上限,就会进入详情形式。最常用的全范围写法是 - + 10,表示从最小 ID 到最大 ID,最多读取 10 条 PEL 记录。

# 读取全组最早的 10 条 pending 详情
redis-cli XPENDING mystream workers - + 10

# 结果每行依次是:消息 ID、消费者、空闲毫秒数、投递次数
# 1) 1) "1710000000000-0"
#    2) "consumer-a"
#    3) (integer) 92400
#    4) (integer) 1

四个返回值要分开理解:

字段含义排查用途
消息 IDStream 条目的 ID后续用 XRANGE 定位消息正文
消费者当前持有该 pending 条目的消费者判断是否集中在某个消费实例
空闲毫秒数距离上次投递给该消费者经过的时间筛选长时间未处理的条目
投递次数该条目被投递的累计次数观察重复投递或反复接管迹象

XPENDING 只返回 PEL 元数据,不包含消息字段。确定某个 ID 需要查看正文时,再单独执行同 ID 的 XRANGE;不要把“查到了 pending”误认为“消息已经被确认”。

用 IDLE 筛出长时间未处理的消息

IDLE 的单位是毫秒。下面的命令只保留空闲时间至少 60 秒的 pending 条目,并把结果限制为 20 条:

# 只看空闲至少 60 秒的 pending 消息,最多返回 20 条
redis-cli XPENDING mystream workers IDLE 60000 - + 20

# 进一步只观察 consumer-a 名下的长时间空闲消息
redis-cli XPENDING mystream workers IDLE 60000 - + 20 consumer-a

这里的 IDLE 60000 是筛选条件,不会改变消息的归属,也不会自动触发确认或转交。Redis 官方文档从 6.2.0 起记录了这个选项;如果部署版本低于该能力范围,应先按实际版本文档确认命令支持情况。

XPENDING 的 IDLE、ID 范围、count、consumer 与消息级返回字段的静态关系图
图2:边界说明图,展示 XPENDING 的空闲筛选和分页参数如何限定 PEL 观察范围,不是运行结果。

用游标和边界控制持续排查

PEL 很大时,固定使用小的 count,并把上一批最后一个消息 ID 加上左括号作为下一批起点。例如第一批返回到 1710000001200-0,下一次可以从 (1710000001200-0 开始,避免重复读取同一条。

# 第一页:从最小 ID 开始,最多读取 20 条
redis-cli XPENDING mystream workers - + 20

# 第二页:排除上一页最后一个 ID,继续向后读
redis-cli XPENDING mystream workers '(1710000001200-0' + 20

如果只关心某一消费者,把消费者名放在最后;如果既要过滤空闲时间又要分页,就保持 IDLE min-idle-time start end count [consumer] 的顺序。count 是本次最多返回的条目数,不是全组 pending 总数。

看到空闲消息后,下一步该怎么判断

先用消息 ID 配合 XRANGE 看正文,再结合消费者实例的日志、处理耗时和投递次数判断原因。若实例已经失联或确认无法继续处理,恢复动作应由明确的故障处理流程决定;XPENDING 本身只是只读观察命令,不会替你执行 XCLAIM 或 XAUTOCLAIM。

  • pending 总数持续增加:先确认消费端是否仍能读取和确认。
  • 空闲毫秒数很大但投递次数为 1:更像是首次投递后长期未确认,需要查消费者存活和处理卡点。
  • 投递次数反复增加:优先检查重复投递、处理失败和接管策略,避免只按空闲阈值盲目转交。
  • 只看到 ID 看不到字段:这是正常结果,用 XRANGE 按 ID 读取正文。

常见问题

XPENDING 的空闲时间是从什么时候开始算?

它表示消息最近一次投递给当前消费者后经过的毫秒数。重新投递或被其他消费者接管后,这个值会重新反映新的投递关系。

能不能用 XPENDING 直接确认消息?

不能。XPENDING 只查询 pending entries list;业务处理成功后仍需由消费逻辑调用 XACK,恢复流程则另行使用合适的接管命令。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>