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 条目。

用详情形式读取消息级字段
在命令后补上起始 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
四个返回值要分开理解:
| 字段 | 含义 | 排查用途 |
|---|---|---|
| 消息 ID | Stream 条目的 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 起记录了这个选项;如果部署版本低于该能力范围,应先按实际版本文档确认命令支持情况。

用游标和边界控制持续排查
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,恢复流程则另行使用合适的接管命令。
-
161 收藏
-
166 收藏
-
293 收藏
-
340 收藏
-
321 收藏
-
354 收藏
-
227 收藏
-
395 收藏
-
189 收藏
-
264 收藏
-
217 收藏
-
267 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习