Redis 的 PUBLISH 命令是发布/订阅(Pub/Sub)模式中的核心指令之一,主要用于向指定的频道(Channel)发送消息,所有订阅该频道的客户端都会接收到这条消息,这一机制为 Redis 提供了一种轻量级的消息通信能力,适用于实时通知、消息推送、系统解耦等场景,以下从命令语法、工作机制、使用场景、注意事项及实践案例等方面展开详细说明。

PUBLISH 命令基础语法与功能
PUBLISH 命令的基本语法为:
PUBLISH channel message
channel 是频道的名称,为字符串类型;message 是要发送的消息内容,可以是任意格式的数据(如字符串、JSON、二进制数据等),命令执行后,会返回一个整数,表示成功接收该消息的订阅者数量(不包括发送方自身)。
PUSH news "Breaking News: Redis 7.0 Released"
若当前有 3 个客户端订阅了 news 频道,命令将返回 3。
发布/订阅机制的核心组件
Redis 的 Pub/Sub 模式包含三个核心角色:
- 发布者(Publisher):通过 PUBLISH 命令发送消息的客户端,无需关注订阅者的存在。
- 频道(Channel):消息的传输通道,发布者将消息发送到指定频道,订阅者通过订阅频道接收消息,频道名称是全局唯一的,不同频道之间消息隔离。
- 订阅者(Subscriber):通过
SUBSCRIBE、PSUBSCRIBE等命令订阅频道的客户端,订阅后可实时接收对应频道的消息。
订阅者可通过 UNSUBSCRIBE 或 PUNSUBSCRIBE 取消订阅,取消后不再接收相关消息。

PUBLISH 命令的工作流程
- 订阅阶段:客户端执行
SUBSCRIBE channel命令后,Redis 会将该客户端与频道建立关联,并维护一个订阅关系表(存储在 Redis 内存中)。 - 消息发布阶段:发布者执行
PUBLISH channel message,Redis 会查找订阅关系表中该频道的所有订阅者,并将消息逐个发送给这些客户端。 - 消息接收阶段:订阅者客户端会阻塞式接收消息(除非使用非订阅模式或独立线程处理),消息格式为:
message channel message-content
message是固定前缀,channel是频道名,message-content是实际消息内容。
PUBLISH 命令的使用场景
- 实时通知系统:如用户消息推送、订单状态更新、系统告警等,电商系统中,订单支付成功后,通过 PUBLISH 向
order:paid频道发送消息,通知物流系统、库存系统同步处理。 - 日志收集与分发:多个服务端将日志发布到指定频道(如
logs:info),日志收集服务订阅该频道并统一处理。 - 任务队列解耦:生产者通过 PUBLISH 发布任务消息,消费者订阅频道并执行任务,避免直接调用导致的耦合问题。
- 多端数据同步:如在线协作文档,用户操作通过 PUBLISH 广播,其他客户端实时同步内容。
PUBLISH 命令的注意事项
- 消息可靠性:Pub/Sub 是“即发即弃”模式,消息不会持久化,若订阅者在发布时离线,上线后将无法接收历史消息,对消息可靠性要求高的场景需结合 Redis Streams 或其他消息队列(如 Kafka、RabbitMQ)。
- 性能影响:若单个频道的订阅者过多(如数万级别),PUBLISH 命令的执行时间会延长,可能影响 Redis 性能,建议通过分频道、集群部署或消息中间件优化。
- 内存占用:订阅关系表存储在 Redis 内存中,大量频道和订阅者可能占用较多内存,需合理设计频道名称(如使用哈希模式减少冗余)。
- 命令阻塞:订阅者客户端执行
SUBSCRIBE后会进入阻塞状态,需通过独立线程或异步机制处理消息,避免阻塞主业务逻辑。
实践案例:简单实时通知系统
假设需要实现一个用户注册成功后的实时通知功能,流程如下:
- 服务端(发布者):用户注册成功后,执行
PUBLISH user:registered "user_id:12345"。 - 通知服务(订阅者):订阅
user:registered频道,接收到消息后调用短信/邮件接口发送通知。
代码示例(Python):
# 发布者
import redis
r = redis.Redis(host='localhost', port=6379)
r.publish('user:registered', 'user_id:12345')
# 订阅者
pubsub = r.pubsub()
pubsub.subscribe('user:registered')
for message in pubsub.listen():
if message['type'] == 'message':
print(f"Received: {message['data']}")
# 处理通知逻辑
相关问答FAQs
问题1:PUBLISH 命令发送的消息是否会被持久化?如果订阅者离线,上线后能否收到消息?
解答:PUBLISH 命令发送的消息不会被持久化,Redis Pub/Sub 是实时广播机制,消息仅在发布时传递给当前在线的订阅者,若订阅者在发布时离线,或因网络问题未连接,上线后将无法接收该历史消息,对消息可靠性有要求的场景,建议使用 Redis Streams(支持持久化、消费组)或专业消息队列。
问题2:如何查看当前 Redis 中所有频道的订阅者数量?
解答:可以通过 PUBSUB NUMSUB [channel1, channel2, ...] 命令查看指定频道的订阅者数量。
PUBSUB NUMSUB news sports
返回结果示例:
- "news", 3
- "sports", 1
3 和 1 分别表示news和sports频道的订阅者数量,若不指定频道,则返回所有频道的订阅者数量,但需注意该命令会阻塞 Redis,不建议在生产环境频繁使用。
