Redis PUB/SUB本质是内存广播而非消息队列,不提供重发机制,因消息不存历史、不记offset、不等ACK、不落盘,断连即丢;client-output-buffer-limit是熔断开关而非重发开关,调大仅延迟断连,无法实现可靠传递。

Redis PUB/SUB 本质是内存广播,不是消息队列
它根本没设计“重发”这回事——PUBLISH 执行完,消息就立刻拷贝到每个活跃订阅者的输出缓冲区,然后原始副本立即释放。不存历史、不记 offset、不等 ACK、不落盘。断连那一刻,缓冲区里没来得及消费的消息全丢,连“从哪重发”这种问题都不存在。
client-output-buffer-limit pubsub 不是重发开关,而是熔断开关
很多人调大这个配置以为能“防丢”,其实只是把强制断连的时间点往后推而已。比如默认 client-output-buffer-limit pubsub 8mb 2mb 60:缓冲区超 2MB 持续 60 秒,或直接突破 8MB,Redis 就 close(fd),清空缓冲区,连接归零。改成 32mb 8mb 60 只会让丢得更晚一点,但依然不持久化;设成 0 0 0 更危险——失去保护,可能触发 OOM 直接拖垮 Redis 实例。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
重复消费和丢消息,都是架构误用的表象
真正的问题不是“怎么让 SUBSCRIBE 不丢消息”,而是“为什么用它承担必须可靠送达的业务”。比如订单创建、支付回调、库存扣减这类场景,SUBSCRIBE 本就不该出现在架构图里。它适合的只有三类信令:CPU 使用率推送、部署完成事件、用户上线广播——丢了不影响业务正确性,下一次心跳或刷新就能覆盖。
想重发?得换命令,还得改代码逻辑
换成 XADD/XREADGROUP 很容易,难的是让业务承担起消息生命周期管理:谁建消费者组、谁调 <code>XACK、断连后怎么补 <code>XRANGE、积压量告警怎么配、<code>XTRIM 阈值怎么定。这些不是改个配置就能解决的,得嵌进业务逻辑里去。

















