首页/数据/Redis 进阶速查/Stream 消费组:XGROUP 与 XREADGROUP
数据结构与选型42 条

Stream 消费组:XGROUP 与 XREADGROUP

消费组把同一条消息分发给组内多个消费者实现分流:XGROUP CREATE 建组,XREADGROUP 用 > 读新消息,处理完成后 XACK 确认,未确认消息进入 PEL。

Redis 进阶速查数据更新于 2026-10-13

Stream 消费组是什么

消费组让一条 Stream 里的消息能被多个消费者分摊处理:组内的每个消费者拿到互不相同的消息,实现水平扩容;不同消费组之间互不影响,同一批消息可以被多个团队各消费一遍。消费者用 XREADGROUP 读取新消息,处理完成后用 XACK 确认。未确认的消息不会消失,而是留在待处理列表(PEL)里归属到具体消费者身上,可以事后重新分配或重投。

基本信息

建组XGROUP CREATE key group $ MKSTREAM,$ 表示只消费之后的新消息
读取XREADGROUP GROUP g c COUNT n STREAMS key >,> 表示只要新消息
确认XACK key group id,成功后消息从 PEL 中移除
查看XINFO STREAM / XINFO GROUPS / XINFO CONSUMERS
组状态记录每个组最后投递的 ID,决定组内的消费进度

典型使用场景

  • 订单事件分发:多个消费者实例并行处理,组内竞争实现负载均衡
  • 多订阅方各取所需:支付组与风控组各自建消费组,同一批事件被两份业务独立处理
  • 任务队列改造:用消费组替代 List 加 BRPOP,获得确认与重投能力而不必额外实现
  • 灰度与回溯:新建消费组从 0 开始读,把历史事件重新处理一遍
  • 故障恢复:消费者宕机后其未确认消息留在 PEL,运维可查看并重新分配

建组读取与确认

建组读取与确认
redis-cli XGROUP CREATE orders g1 0 MKSTREAM          # 从头开始消费并自动建流
redis-cli XREADGROUP GROUP g1 consumer1 COUNT 10 STREAMS orders '>'   # 只读新消息
redis-cli XACK orders g1 1730020000000-0             # 处理完成,从 PEL 移除
redis-cli XREADGROUP GROUP g1 consumer1 COUNT 10 STREAMS orders 0    # 读自己的历史未确认
redis-cli XINFO GROUPS orders                          # 各组 pending 与 last-delivered-id
redis-cli XINFO CONSUMERS orders g1                    # 组内消费者与各自未确认数

起点 ID 的含义

起点写法含义使用场景
0从最早的消息开始消费回溯处理历史事件,或新建组补数据
$只消费建组之后写入的新消息线上常规做法,避免一上线就压满历史
>读取尚未投递给本组的新消息XREADGROUP 的常规参数
具体 ID从指定 ID 之后开始断点续传或按业务时间点重放
不确认的后果:消息一直留在待处理列表里,既不消失也不会被重新投递给其他消费者。待处理条数持续增长会占用内存,也意味着有业务没被处理。生产中应监控 XPENDING 的数量与最老消息的空闲时间,并对僵尸消费者做告警。
顺序保证的边界:同一消费者按 ID 顺序读到消息,因此单消费者维度内是有序的;但多个消费者并行处理时,跨消费者的全局顺序不再成立。要求严格有序的业务应只用一个消费者,或在业务侧按主键做串行化。

易错点

  • 消费者读取后崩溃且未执行 XACK,消息长期滞留在待处理列表,业务侧表现为部分订单永远不再被处理
  • 所有消费者共用同一个消费者名,组内无法区分归属,待处理消息无法定向排查与认领
  • 用 > 读取后误以为能读到历史未确认消息,实际只能拿到新消息,读自己的历史必须把 > 换成 0
  • 建组时用了 $ 却期望处理历史事件,导致上线后老数据无人处理,应该用 0 或指定 ID 建组

数据来源与参考

  • Redis 官方文档:XGROUP / XREADGROUP 命令
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌