704 字
4 分钟
Redis Stream 如何保证消息消费?ACK 和 PEL 是什么?
  1. 1Redis 系列导读:知识地图、必会主线与复习顺序
  2. 2Redis 中常见的数据类型有哪些?
  3. 3Redis 通常应用于哪些场景?
  4. 4Redis为什么这么快?
  5. 5Redis 常用的过期时间、删除 Key 命令有哪些?
  6. 6Redis 的过期 Key 是如何被删除的?
  7. 7Redis 内存满了怎么办?有哪些淘汰策略?
  8. 8缓存穿透、击穿、雪崩的区别与解决方案
  9. 9Redis 如何保证缓存与数据库的数据一致性?
  10. 10Redis 的持久化机制有哪些?
  11. 11Redis 主从复制的完整流程是什么?
  12. 12Redis 的哨兵机制是什么?
  13. 13Redis Cluster 模式与 Sentinel 模式的区别是什么?
  14. 14Redis 支持事务吗?如何实现?
  15. 15Redis 中如何实现分布式锁?
  16. 16Redis 的 Lua 脚本功能是什么?如何使用?
  17. 17如何解决 Redis 中的热点 Key 问题?
  18. 18Redis BigKey 有什么危害?如何发现和治理?
  19. 19为什么 Redis 设计为单线程?6.0 版本为何引入多线程?
  20. 20Redis 的 LRU 和 LFU 有什么区别?
  21. 21Redis 数据类型和底层编码有什么区别?
  22. 22Redis 中跳表的实现原理是什么?
  23. 23Redis 的 ZSet 为什么使用跳表,而不是平衡树?
  24. 24Redis 的 RDB 快照如何生成?为什么会有写时复制?
  25. 25Redis 的 AOF 刷盘和重写有什么区别?
  26. 26Redis 断线后如何通过 PSYNC 部分重同步?
  27. 27Redis 主从切换为什么会丢数据?WAIT 能解决吗?
  28. 28Redis 集群会出现脑裂问题吗?
  29. 29Redisson 看门狗(watch dog)机制了解吗?
  30. 30Redis Cluster:哈希槽、Gossip 与故障转移
  31. 31Redis Pipeline 为什么能提高吞吐?能保证原子性吗?
  32. 32Redis 的 SCAN 和 KEYS 有什么区别?
  33. 33Redis 变慢时如何排查?SLOWLOG 能看到所有耗时吗?
  34. 34Redis 和 MySQL 有什么区别?
  35. 35Redis 为什么使用 SDS,而不是 C 字符串?
  36. 36Redis 的哈希表如何处理冲突和渐进式 rehash?
  37. 37Redis Cluster 的 MOVED 和 ASK 重定向有什么区别?
  38. 38Redis Cluster 为什么会报 CROSSSLOT?Hash Tag 怎么用?
  39. 39Redis 如何实现限流?固定窗口和滑动窗口怎么选?
  40. 40Redis Stream 如何保证消息消费?ACK 和 PEL 是什么?本文
  41. 41Redis 删除数据后为什么内存不下降?如何理解内存碎片?

Redis Stream 保存带 ID 的消息,消费组记录消费进度与未确认消息。相比简单 Pub/Sub,它允许消费者离线后继续读取、追踪处理中消息,并由其他消费者接管。这些机制有助于实现至少一次处理,不自动保证业务恰好执行一次。

一条消息经历什么?#

生产者 XADD 写入消息;创建消费组后,消费者通过 XREADGROUP 读取新消息。未使用 NOACK 等特殊方式时,已投递但尚未确认的消息进入组内待确认列表 PEL。消费者成功完成业务后调用 XACK,从 PEL 移除相应记录,但不会因此自动删除 Stream 中的消息内容。

XADD jobs * type email user_id 1001
XGROUP CREATE jobs workers 0 MKSTREAM
XREADGROUP GROUP workers worker-1 COUNT 10 STREAMS jobs >
# 实际完成业务后,对返回的具体消息 ID 执行 XACK

例子选择从 0 开始建组,表示已有消息也可读取;从 $ 开始则关注创建时位置之后的新消息。这是一次性建组示例,已存在消费组时不能每次启动都不加处理地重复创建。

消费者宕机怎么办?#

XPENDING 可观察待确认消息。对于长时间未完成的消息,可以按版本使用 XCLAIM 或 XAUTOCLAIM 接管,再处理并确认。接管阈值应超过正常处理时间,否则一个仍在工作的消费者与接管者可能重复执行。业务用消息 ID、订单号或唯一约束实现幂等,还应设置重试上限和失败处理渠道。

Stream 的持久性仍依赖 Redis 的持久化和复制配置。修剪与删除也要考虑未处理消息,不能只为了限制长度就无条件删除业务尚未消费的历史。

常见追问#

处理完业务但 XACK 前宕机,会发生什么?#

消息可能被再次接管,业务重复处理;幂等设计应能识别已经成功完成的操作。

先 XACK 再执行业务可以避免重复吗?#

这会引入丢处理风险:确认后宕机,系统可能认为消息已完成,但业务未执行。通常先完成业务再确认,并处理重复。

Pub/Sub 为什么不适合可靠任务投递?#

它主要是即时广播,不为离线订阅者保存消费积压,也没有相同的确认与接管机制;断开期间的消息不能靠重新订阅自动补回。

不同消费组之间会争抢同一条消息吗?#

各组有自己的进度,可以独立消费同一 Stream。组内消费者分担工作,组间则可以分别实现日志、通知等不同职责。

Redis Stream 如何保证消息消费?ACK 和 PEL 是什么?
https://blog.xqcherry.top/posts/interview/redis/redis-streams-reliability/
作者
xqcherry
发布于
2026-10-12
许可协议
CC BY-NC-SA 4.0