本文是大数据系列第 42 篇,深入分析 Redis Pub/Sub 的发布订阅机制、弱事务特性及其在分布式系统中的适用边界。

完整图文版(含截图):CSDN 原文 | 掘金

核心概念

Redis Pub/Sub 是一种消息通信模式,发布者(Publisher)和订阅者(Subscriber)都是 Redis 客户端,频道(Channel)存在于服务端。三者解耦,发布者无需知道谁在订阅,订阅者也无需关心谁在发布。

基础命令

# 订阅一个或多个频道
SUBSCRIBE channel1 channel2

# 模式订阅(支持通配符)
PSUBSCRIBE news.*

# 向频道发布消息
PUBLISH channel message

# 取消订阅
UNSUBSCRIBE channel1
PUNSUBSCRIBE news.*

工作机制

Pub/Sub 的运行遵循以下原则:

  1. 消息不持久化:Redis 不保存消息,消息仅推送给当前已连接的订阅者
  2. Fire-and-Forget 模型:消息发出后不等待任何确认,也不做重试
  3. 自动取消订阅:客户端断开连接后,订阅关系自动失效

订阅者执行 SUBSCRIBE 后进入阻塞接收模式,此时只能执行订阅相关命令(SUBSCRIBEUNSUBSCRIBEPSUBSCRIBEPUNSUBSCRIBEPING),不能执行其他 Redis 命令。


弱事务三大缺陷

Redis Pub/Sub 被称为”弱事务”模型,主要体现在以下三点:

1. 投递不可靠

消息发布时如果没有活跃订阅者,消息立即丢弃。典型场景:系统扩容新增消费者节点时,扩容前已发布的消息对新消费者完全不可见。

2. 无确认机制

发布者发出消息后,无法得知哪些订阅者收到了消息、是否处理成功。这导致无法实现可靠投递语义(at-least-once 或 exactly-once)。

3. 无重试逻辑

网络抖动或消费者故障期间发布的消息,Redis 不会自动重发。消息永久丢失,没有死信队列(Dead Letter Queue)机制兜底。


生产环境风险

场景风险
移动客户端断线重连断线期间所有消息丢失
消费者服务重启重启期间消息无法补偿
网络分区消息单向丢失,无感知
水平扩容消费者扩容前消息对新节点不可见

Redis 事务(MULTI/EXEC)的弱点

与 Pub/Sub 类似,Redis 事务也有弱事务特性:

  • 不支持回滚:EXEC 执行过程中某条命令出错,其他命令仍会继续执行
  • 不支持隔离性:MULTI 到 EXEC 之间,其他客户端可以插入命令(需配合 WATCH 实现乐观锁)
  • 设计取舍:Redis 刻意牺牲部分 ACID 特性换取高吞吐量
MULTI
SET key1 value1
SET key2 value2
EXEC

替代方案选择

需求推荐方案
消息可靠投递 + 持久化Redis Stream
高吞吐 + 分布式消费Apache Kafka
企业级消息队列RabbitMQ
简单实时广播(允许丢消息)Redis Pub/Sub

结论:Redis Pub/Sub 适合对消息丢失不敏感的实时广播场景(如在线用户状态推送、实时通知),不适合金融交易、订单状态变更等对消息可靠性有强要求的场景。需要可靠消息队列时,优先考虑 Redis Stream 或 Kafka。