Redis Stream 消费组怎样使用 NOACK
Redis Stream 消费组在 XREADGROUP 中加上 NOACK,可以让本次读取的新消息不进入 Pending Entries List(PEL)。典型写法是 XREADGROUP GROUP 组名 消费者名 COUNT 100 NOACK STREAMS 流名 >。代价是:它把读取视作已确认,不等业务处理完成;消费者随后失败时,这些消息没有该组的 Pending 记录可供接管。
如果只是允许偶发缺失的实时展示,我会考虑它;如果是必须补偿的订单处理,我会保留普通消费与成功后的 XACK。这里用一个假设的实时展示任务解释选择,不声称亲历了故障或完成了压测。
官方命令地址:https://redis.io/docs/latest/commands/xreadgroup/
我会先把处理成功单独计数
假设有一个活动看板,把消息交给多个消费者做短时展示。旧消息很快失去展示价值,但是否允许丢失仍然需要业务明确决定。我不会先问“能快多少”,而会先区分三个数量:消费端收到多少条、业务真正完成多少条、组内还有多少条 Pending。
NOACK 最容易造成的误判,是 Pending 变成零后就认为任务全部成功。对我而言,零 Pending 只说明没有相应待确认记录,不等于每条消息的业务动作已完成。测量基线应保留业务成功计数,而不是只保留 Redis 返回数量。
| 计数 | 观察对象 | 不能代替什么 |
|---|---|---|
| 读取条数 | 客户端实际收到的消息 | 业务完成条数 |
| 成功条数 | 业务动作完成的消息 ID | 全部曾读取的消息 |
| Pending 条数 | PEL 中的待确认记录 | NOACK 模式下的失败条数 |
NOACK 省下的是待确认记录
普通消费组会跟踪已投递但未确认的消息,业务成功后用 XACK 移除相应 PEL 记录。NOACK 则跳过新消息的这份待确认记录。因此它改变的是确认与恢复约定,不是把业务处理变成 Redis 内部的原子操作。
在这个区别里,我会把 Stream 消息本体、PEL 与业务处理结果分开看。NOACK 不是删除 Stream 条目的命令;即便消息仍在 Stream 中,也不代表业务知道哪些已成功、哪些需要重做。保留的条目可以按 ID 范围查询,另做重放则需要自己定义范围、完成记录和去重规则,不能当作 Pending 接管的等价替代。
有关确认职责可参照官方 XACK 说明:https://redis.io/docs/latest/commands/xack/;原始条目的范围查询见:https://redis.io/docs/latest/commands/xrange/。

把 NOACK 放到新消息读取中
下面是 shell 中的命令片段,假设流与组已经存在。注意把 > 引起来,避免 shell 将它当作输出重定向。
# 读取该组尚未投递的新消息,最多等待 1000 毫秒;不建立新消息的 PEL 记录 redis-cli XREADGROUP GROUP display_group worker_a COUNT 100 BLOCK 1000 NOACK STREAMS display_events '>'
GROUP 后面依次是组名和消费者名;组内不同工作实例应使用不同消费者名。COUNT 是每条流的数量上限,并不是必须凑满的批量大小。BLOCK 控制无可读消息时的等待,1000 的单位是毫秒,不是业务处理超时。
这里没有使用 CLAIM 扩展,> 表示读取该组尚未投递的新消息。若改用 0 或其他具体 ID,含义变成读取当前消费者已有的 Pending;此时 NOACK 与 BLOCK 被忽略。不要靠 NOACK STREAMS 流名 0 清空历史待确认记录。以上范围以官方 XREADGROUP 规则为准。
用两个组比较同一批消息
下面的示例供读者在独立测试实例执行,未在本机运行。前提是 demo:noack:events 这个键此前不存在,没有其他生产者、消费者或裁剪操作;两个组使用相同起点,从而能分别消费同样的两条消息。固定 ID 只用于教学,不表示真实生成时间。
# 创建两个独立组;起点 0 允许读取从头保留的消息,MKSTREAM 创建空流 redis-cli XGROUP CREATE demo:noack:events fast_group 0 MKSTREAM redis-cli XGROUP CREATE demo:noack:events tracked_group 0 # 在新建的空流中写入两条示例事件,固定 ID 便于后续引用 redis-cli XADD demo:noack:events 1-0 event_key screen_a value 17 redis-cli XADD demo:noack:events 2-0 event_key screen_b value 29 # 同一批消息由不同组分别读取;fast_group 不建立 Pending redis-cli XREADGROUP GROUP fast_group fast_a COUNT 2 NOACK STREAMS demo:noack:events '>' redis-cli XREADGROUP GROUP tracked_group tracked_a COUNT 2 STREAMS demo:noack:events '>' # 比较各组 Pending,并单独查看仍保留的消息本体 redis-cli XPENDING demo:noack:events fast_group redis-cli XPENDING demo:noack:events tracked_group redis-cli XRANGE demo:noack:events - + COUNT 2 # 仅当对应业务处理成功时,普通消费组才确认这些 ID redis-cli XACK demo:noack:events tracked_group 1-0 2-0
按命令语义预期,两个读取都可得到两条事件;fast_group 的 Pending 数量为 0,tracked_group 在确认前为 2。两条原始消息仍可通过 XRANGE 查询;最后的 XACK 移除普通组的待确认记录。这些是基于前提的预期,不是实测输出,也不是吞吐基准。
普通组最后的 XACK 演示确认动作的位置,不能照抄到业务失败分支。示例对象留在测试实例中,不自动清理其他键。若创建时返回 BUSYGROUP,说明组已存在,应停止并换未使用的测试对象,不能继续拿旧组状态作对照。
组起点与创建行为参照:https://redis.io/docs/latest/commands/xgroup-create/;Pending 查询参照:https://redis.io/docs/latest/commands/xpending/。
性能收益要和缺失代价一起量
少维护一份记录、少一次确认动作,可能减少开销,但我不会由此直接写出“性能提升一倍”。普通消费也可以批量 XACK,网络、业务耗时和批量大小都可能掩盖差异。真正的对比需要相同消息内容、消费者数量、并发、网络条件与持久化设置。
如果由我安排实验,会使用两轮隔离负载:一轮普通读取并在业务成功后批量确认,一轮 NOACK。每轮固定消息数量,记录相同观测窗口;除了读取速率,还要记录业务成功速率、端到端 P95 延迟、客户端和 Redis CPU,以及按实际成功 ID 计算的缺失情况。
| 指标 | 普通读取+确认 | NOACK |
|---|---|---|
| 业务成功条数/秒 | 需实测 | 需实测 |
| 端到端 P95 延迟 | 需实测 | 需实测 |
| CPU 与资源开销 | 需实测 | 需实测 |
| 读取后进程退出的未完成 ID | 观察 Pending 与恢复结果 | 观察业务缺失与外部补偿 |
故障实验也只应在测试环境进行:让消费者读取后、业务完成前退出,再比较未完成消息的可定位性。普通组虽然保留 Pending,仍要实现接管、重试和业务幂等;NOACK 则没有这些新消息的 PEL 依据。我的判断会同时看速度变化和缺失是否符合约定,而不是只挑吞吐好看的数字。

需要补偿时我会保留确认机制
对临时展示、允许明确范围内缺失的非关键数据,NOACK 可以是一个简化选择。但如果处理失败必须知道“哪一条没完成”,我会保留 PEL 与显式确认。业务要求不能因为 Pending 看起来更干净而被悄悄改变。
切换选项还要记住:NOACK 是本次读取的选择,不是永久关闭消费组的确认能力。之前积累的 Pending 不会被它自动清掉;后续不带 NOACK 的新消息仍按普通确认约定处理。混用前必须让监控能识别哪些消息采用了哪种处理策略。
常见问题
NOACK 的消息还需要 XACK 吗?对于该方式新读取且未加入 PEL 的消息,不需要用 XACK 移除不存在的记录;业务成功仍应自行记录。
Pending 为零能说明没有失败吗?不能。尤其在 NOACK 下,它没有收集这批消息的业务失败情况。
消息仍在 Stream 里,为什么不能直接补偿?原始事件不等于完成状态。重放前还需确定缺失范围与去重约定,不能把所有历史事件无差别重复处理。
我的取舍是:先明确可容忍的缺失,再衡量省下的开销。NOACK 解决的是“不需要维护待确认记录”,不是“可靠消费无需确认”。
MySQL 只读事务怎样减少误写风险
- 上一篇
- MySQL 只读事务怎样减少误写风险
- 下一篇
- Redis XAUTOCLAIM 怎样只取消息 ID 做恢复
-
- 数据库 · Redis | 56分钟前 |
- Redis BZPOPMIN 怎样等待最小成员
- 454浏览 收藏
-
- 数据库 · Redis | 1小时前 |
- Redis BLMOVE 超时后怎样判断源列表状态
- 108浏览 收藏
-
- 数据库 · Redis | 1小时前 |
- Redis 客户端缓存怎样使用广播失效
- 332浏览 收藏
-
- 数据库 · Redis | 1小时前 |
- Redis ACL 怎样限制用户可订阅的频道前缀
- 269浏览 收藏
-
- 数据库 · Redis | 1小时前 | 函数 · Redis · Redis Functions 只读副本 FCALL_RO no-writes
- Redis FCALL_RO 怎样调用只读函数
- 495浏览 收藏
-
- 数据库 · Redis | 1小时前 |
- Redis SET 怎样覆盖值但保留原 TTL
- 379浏览 收藏
-
- 数据库 · Redis | 1小时前 | Redis · Stream · redis 消息恢复 XAUTOCLAIM Redis Streams JUSTID
- Redis XAUTOCLAIM 怎样只取消息 ID 做恢复
- 187浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 474次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 532次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 552次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 505次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 324次使用
-
- Redis Stream XTRIM 如何避免消费组积压无限增长
- 2026-09-12 501浏览
-
- Redis AOF rewrite 期间如何判断磁盘与内存压力
- 2026-09-12 501浏览
-
- Redis RDB 和 AOF 怎么按可接受数据丢失量选择
- 2026-09-08 501浏览
-
- Redis XAUTOCLAIM 之后为什么仍有 pending:JUSTID、PEL 与消息删除边界
- 2026-08-29 501浏览
-
- Redis SET 的 GET 与 KEEPTTL 怎么一起验收:旧值返回、续期与回滚边界
- 2026-08-20 501浏览
