publish返回成功不等于消息可靠送达,因其仅表示写入redis内部管道、未校验接收处理、无重试落盘、不记录offset;真正可靠需组合stream持久化+主动拉取+超时兜底。

PUBLISH 和 SUBSCRIBE 本身不提供可靠性保障,所谓“可靠的通知”必须靠外部机制补足。Redis Pub/Sub 是纯内存、无持久化、无确认机制的广播模型——消息发出去就没了,订阅者掉线就丢,发布者也不管谁收到了。
为什么 PUBLISH 返回值不能当作可靠性依据?
PUBLISH 命令返回的是「当前在线且已订阅该频道的客户端数量」,不是「成功送达数量」:
• 它不校验接收方是否处理成功(比如进程崩溃、JSON 解析失败)
• 它不重试、不落盘、不记录 offset
• 如果订阅者正在 reconnect 或刚启动还没 SUBSCRIBE,这个数字就是 0,但你根本不知道它是否曾在线
如何让通知“看起来可靠”?
实际项目中想用 Redis 做命令通知,得绕开 Pub/Sub 的天然缺陷,常用组合方案是:
• 用 PUBLISH 触发轻量级唤醒:只发一个简短标识(如 "cmd:reload_config:12345"),不传完整数据
• 真正命令参数走持久化存储:把完整指令写进 SET 或 STREAM,带上时间戳和唯一 ID
• 订阅者收到通知后主动 GET 或 XREAD 拉取详情,失败可重试
• 加超时+重发兜底:比如 5 秒没拉到数据,就查 STREAM 最后 10 条,或 fallback 到轮询
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
别踩 PSUBSCRIBE 的坑:模式匹配不等于路由可靠
用 PSUBSCRIBE 订阅 "cmd.*" 看似灵活,但要注意:
• 匹配逻辑在服务端做,但匹配结果仍受前述可靠性限制
• 多个模式同时匹配同一消息时,会重复推送(比如 cmd.user.* 和 cmd.* 都命中 cmd.user.123)
• PUBSUB NUMPAT 只能查模式数,不能查每个模式下具体有哪些客户端在线
• 模式订阅无法与频道订阅共享连接,混合使用容易漏消息
真正需要可靠命令通知时,该换什么?
如果业务要求「至少一次送达」「支持回溯」「有 ACK 机制」,就该放弃 Pub/Sub:
• STREAM + XGROUP + XREADGROUP:自带消费者组、pending list、ACK 机制,适合命令类强语义场景
• 结合 BLPOP/BRPOP + List:简单队列,支持阻塞读和原子出队,但仅限点对点
• 外部消息中间件(Kafka/RabbitMQ):当通知要跨机房、保序、审计留痕时,别硬扛










