Redis发布订阅 #

一、发布订阅概述 #

1.1 什么是发布订阅 #

发布订阅(Pub/Sub)是一种消息通信模式:

  • 发布者(Publisher):发送消息
  • 订阅者(Subscriber):接收消息
  • 频道(Channel):消息通道
text
发布订阅架构:

┌─────────────────────────────────────────────────────────┐
│                     Redis Server                        │
│                                                         │
│  ┌─────────────────────────────────────────────────┐   │
│  │              Channel: news                      │   │
│  └─────────────────────────────────────────────────┘   │
│       ▲              │              ▲                   │
│       │              │              │                   │
│  ┌────┴────┐    ┌────┴────┐    ┌────┴────┐            │
│  │订阅者1  │    │订阅者2  │    │订阅者3  │            │
│  └─────────┘    └─────────┘    └─────────┘            │
│                                                         │
│  ┌─────────────────────────────────────────────────┐   │
│  │              发布者                             │   │
│  │         PUBLISH news "message"                  │   │
│  └─────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────┘

1.2 特点 #

text
Redis发布订阅特点:

优点:
┌─────────────────────────────────────────────┐
│ 1. 实时消息传递                             │
│ 2. 解耦发布者和订阅者                       │
│ 3. 支持模式匹配订阅                         │
│ 4. 轻量级,易于使用                         │
└─────────────────────────────────────────────┘

限制:
┌─────────────────────────────────────────────┐
│ 1. 消息不持久化                             │
│ 2. 订阅者离线时消息丢失                     │
│ 3. 不保证消息可靠传递                       │
│ 4. 不支持消息确认机制                       │
└─────────────────────────────────────────────┘

二、基本操作 #

2.1 订阅频道 #

bash
# SUBSCRIBE: 订阅频道
SUBSCRIBE news
# Reading messages... (press Ctrl-C to quit)
# 1) "subscribe"   # 消息类型
# 2) "news"        # 频道名
# 3) (integer) 1   # 订阅数

# 收到消息
# 1) "message"     # 消息类型
# 2) "news"        # 频道名
# 3) "hello"       # 消息内容

# 订阅多个频道
SUBSCRIBE news sports weather
# 1) "subscribe"
# 2) "news"
# 3) (integer) 1
# 1) "subscribe"
# 2) "sports"
# 3) (integer) 2
# 1) "subscribe"
# 2) "weather"
# 3) (integer) 3

2.2 发布消息 #

bash
# PUBLISH: 发布消息
PUBLISH news "Hello World"
# (integer) 2  # 收到消息的订阅者数量

PUBLISH news "Breaking News"
# (integer) 2

# 如果没有订阅者
PUBLISH empty:channel "message"
# (integer) 0  # 消息丢失

2.3 取消订阅 #

bash
# UNSUBSCRIBE: 取消订阅
UNSUBSCRIBE news
# 1) "unsubscribe"
# 2) "news"
# 3) (integer) 0  # 剩余订阅数

# 取消所有订阅
UNSUBSCRIBE

2.4 查看订阅信息 #

bash
# PUBSUB CHANNELS: 查看活跃频道
PUBSUB CHANNELS
# 1) "news"
# 2) "sports"

# 查看匹配的频道
PUBSUB CHANNELS news*
# 1) "news"

# PUBSUB NUMSUB: 查看频道订阅者数量
PUBSUB NUMSUB news sports
# 1) "news"
# 2) (integer) 2
# 3) "sports"
# 4) (integer) 1

# PUBSUB NUMPAT: 查看模式订阅数量
PUBSUB NUMPAT
# (integer) 3

三、模式订阅 #

3.1 模式匹配 #

bash
# PSUBSCRIBE: 模式订阅
PSUBSCRIBE news:*
# 1) "psubscribe"
# 2) "news:*"
# 3) (integer) 1

# 收到消息
# 1) "pmessage"      # 消息类型
# 2) "news:*"        # 匹配的模式
# 3) "news:sports"   # 实际频道
# 4) "hello"         # 消息内容

# 多个模式
PSUBSCRIBE news:* sports:* weather:*

3.2 取消模式订阅 #

bash
# PUNSUBSCRIBE: 取消模式订阅
PUNSUBSCRIBE news:*
# 1) "punsubscribe"
# 2) "news:*"
# 3) (integer) 0

# 取消所有模式订阅
PUNSUBSCRIBE

3.3 模式匹配规则 #

text
模式匹配规则:

*  匹配任意数量的任意字符
?  匹配单个任意字符
[] 匹配指定范围内的字符

示例:
news:*        匹配 news:sports, news:weather, news:tech
news:?        匹配 news:a, news:b
news:[aeiou]  匹配 news:a, news:e, news:i, news:o, news:u

四、消息类型 #

4.1 消息类型说明 #

text
订阅消息类型:

1. subscribe / unsubscribe
   ┌─────────────────────────────────────────────┐
   │ 1) "subscribe"                              │
   │ 2) "channel"                                │
   │ 3) (integer) count                          │
   └─────────────────────────────────────────────┘

2. message
   ┌─────────────────────────────────────────────┐
   │ 1) "message"                                │
   │ 2) "channel"                                │
   │ 3) "message content"                        │
   └─────────────────────────────────────────────┘

3. psubscribe / punsubscribe
   ┌─────────────────────────────────────────────┐
   │ 1) "psubscribe"                             │
   │ 2) "pattern"                                │
   │ 3) (integer) count                          │
   └─────────────────────────────────────────────┘

4. pmessage
   ┌─────────────────────────────────────────────┐
   │ 1) "pmessage"                               │
   │ 2) "pattern"                                │
   │ 3) "channel"                                │
   │ 4) "message content"                        │
   └─────────────────────────────────────────────┘

五、应用场景 #

5.1 实时消息推送 #

bash
# 发布者:推送通知
PUBLISH notifications:user:1001 "您有新消息"
PUBLISH notifications:user:1001 "订单已发货"

# 订阅者:用户1001接收通知
SUBSCRIBE notifications:user:1001

5.2 聊天室 #

bash
# 创建聊天室
# 用户加入聊天室
SUBSCRIBE chat:room:1

# 发送消息
PUBLISH chat:room:1 "Hello everyone!"

# 多个聊天室
SUBSCRIBE chat:room:1 chat:room:2

5.3 新闻订阅 #

bash
# 订阅特定类型新闻
SUBSCRIBE news:sports
SUBSCRIBE news:tech

# 或使用模式订阅
PSUBSCRIBE news:*

# 发布新闻
PUBLISH news:sports "体育新闻内容"
PUBLISH news:tech "科技新闻内容"

5.4 事件通知 #

bash
# 系统事件通知
SUBSCRIBE events:system
SUBSCRIBE events:alert

# 发布事件
PUBLISH events:system "服务器重启"
PUBLISH events:alert "CPU使用率过高"

5.5 配置更新 #

bash
# 订阅配置更新
SUBSCRIBE config:update

# 发布配置更新通知
PUBLISH config:update '{"key":"theme","value":"dark"}'

六、Pub/Sub vs Stream #

6.1 对比 #

text
Pub/Sub vs Stream:

┌─────────────────────────────────────────────────────────┐
│                    Pub/Sub                              │
├─────────────────────────────────────────────────────────┤
│ 优点:                                                  │
│ - 实时性强                                              │
│ - 简单易用                                              │
│ - 轻量级                                                │
│                                                         │
│ 缺点:                                                  │
│ - 消息不持久化                                          │
│ - 离线消息丢失                                          │
│ - 不支持消息确认                                        │
│ - 不支持消费者组                                        │
└─────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────┐
│                    Stream                               │
├─────────────────────────────────────────────────────────┤
│ 优点:                                                  │
│ - 消息持久化                                            │
│ - 支持消费者组                                          │
│ - 支持消息确认                                          │
│ - 支持历史消息                                          │
│                                                         │
│ 缺点:                                                  │
│ - 相对复杂                                              │
│ - 需要管理消费进度                                      │
└─────────────────────────────────────────────────────────┘

6.2 选择建议 #

text
选择建议:

使用 Pub/Sub:
- 实时通知
- 简单消息推送
- 在线用户消息
- 不需要消息可靠性

使用 Stream:
- 消息队列
- 需要消息持久化
- 需要消息确认
- 需要消费者组
- 需要历史消息

七、最佳实践 #

7.1 频道命名规范 #

bash
# 推荐的命名规范
user:1001:notifications   # 用户通知
chat:room:1               # 聊天室
news:sports               # 体育新闻
events:system             # 系统事件
config:update             # 配置更新

7.2 消息格式 #

bash
# 推荐使用JSON格式
PUBLISH notifications:user:1001 '{"type":"message","content":"新消息","time":1700000000}'

# 或使用简单分隔符
PUBLISH events:system "alert|CPU使用率过高|1700000000"

7.3 错误处理 #

bash
# 订阅者需要处理异常
# 伪代码
while True:
    try:
        message = subscriber.get_message()
        if message:
            process_message(message)
    except Exception as e:
        log_error(e)
        reconnect()

7.4 连接管理 #

bash
# 使用连接池
# 设置合理的超时时间
# 实现自动重连
# 处理网络断开情况

八、总结 #

发布订阅命令:

命令 说明
SUBSCRIBE 订阅频道
UNSUBSCRIBE 取消订阅
PUBLISH 发布消息
PSUBSCRIBE 模式订阅
PUNSUBSCRIBE 取消模式订阅
PUBSUB CHANNELS 查看活跃频道
PUBSUB NUMSUB 查看订阅者数量

应用场景:

场景 实现方式
实时通知 SUBSCRIBE + PUBLISH
聊天室 SUBSCRIBE + PUBLISH
新闻订阅 PSUBSCRIBE + PUBLISH
事件通知 SUBSCRIBE + PUBLISH

下一步,让我们学习Redis事务!

最后更新:2026-03-27