redis streams 是唯一能支撑生产级事件总线的原生命令方案,因其持久化存储、消费者组偏移管理、pel 未确认消息队列及 xack 机制保障可靠性;而 pub/sub 不存消息、无状态、不重试、不 ack,本质是不可靠广播。

Redis Streams 是唯一能支撑生产级事件总线的 Redis 原生命令方案;Pub/Sub 在大规模场景下本质是“不可靠广播”,不是消息队列。
Pub/Sub 为什么扛不住大数据量
它不存消息、不记订阅者状态、不重试、不 ACK,所有逻辑都是“发完就扔”。哪怕你开了 appendonly yes,PUBLISH 命令本身也不会写入 AOF —— 因为它不改变数据集状态,只触发内存推送。
- 客户端 GC 暂停 200ms?那期间所有
PUBLISH都丢光 - 服务端主从切换时连接断开?正在推送的消息直接中断,无重发机制
- 新扩容一个消费者实例?它连不上“历史”,只能从当前开始收,漏掉上线前全部事件
- 集群模式下跨 slot 的频道(如用哈希标签但没对齐)?
SUBSCRIBE可能失败或路由错位
Streams 如何解决这些痛点
它把消息当数据存,把消费当状态管。每条消息写入即落盘(RDB/AOF),每个消费者组维护独立偏移(last_delivered_id),未 XACK 的消息进 PEL(Pending Entries List),随时可被 XCLAIM 接管。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
-
XADD mystream * event_type "order_created" order_id "12345":消息带时间戳 ID,自动持久化 -
XGROUP CREATE mystream mygroup $:从尾部开始消费;用0则从头回溯 -
XREADGROUP GROUP mygroup consumer1 COUNT 1 STREAMS mystream >:读取未分配的新消息 - 消费者处理完必须调
XACK mystream mygroup 1718234567890-0,否则下次还会读到它
别被“吞吐高”误导:Pub/Sub 的性能优势是假象
看似 PUBLISH 很快,是因为它不做任何持久化和状态管理。但代价是:所有订阅者共享同一份内存拷贝,100 个客户端 = 100 份序列化+网络发送;而 Streams 的读压力在客户端,服务端只是按 ID seek 日志段,横向扩展更平滑。
- Pub/Sub 连接数上涨 → Redis 内存暴涨 + 网络 buffer 打满 →
OOM error或连接被踢 - Streams 单个
XREADGROUP请求只拉自己该读的几条,支持COUNT和BLOCK控制节奏 - 用
XTRIM mystream MAXLEN 1000000可控保留窗口,不靠人工删 key
真正容易被忽略的是语义鸿沟:用 PUB/SUB 做订单事件分发,等于默认接受“支付成功但库存没扣、通知没发、积分没加”这种故障;而 Stream 的 XACK + PEL + 消费者组自动负载均衡,才是把可靠性落到每一行代码里的做法。










