Redis 的订阅发布功能是什么?你了解吗?
Redis 的订阅发布功能是什么?你了解吗?
回答重点
Redis 的订阅发布功能(Publish/Subscribe,简称 Pub/Sub),是一种消息通信机制,用于在不同客户端之间实现消息的实时传递和广播。使用 Pub/Sub 模型,客户端可以订阅一个或多个频道,当有其他客户端向这些频道发布消息时,所有订阅了该频道的客户端都会立即收到消息。
主要功能包括:
- 发布(Publish):某个客户端向指定的频道发布消息。
- 订阅(Subscribe):一个或多个客户端订阅指定的频道,并在频道接收到消息时立刻获取该消息。
扩展知识
什么是发布/订阅模型?
发布/订阅其实属于消息队列中的一种消息通信模型,生产者(pub)发送消息,订阅者(sub)接收消息。
这里我们展示一下 Redis 的发布/订阅逻辑。如下图所示,发布者向一个或者多个频道发布消息,订阅者可以订阅一个或者多个频道所发布的消息。
当发布者发送新消息到对应的频道的时候,订阅者可以收到对应的信息。
Redis 实现发布/订阅
简单演示下 Redis 发布/订阅模型的使用。
首先我们先创建并发布一个 message 到 Redis 频道,这里我们用三条信息进行对应的测试,如图所示
1 | publish channel message |
然后实现对应的频道订阅
1 | subscribe channel |
可以看到,频道发布的消息都被消费到了。
解析下上述结果。
首先是 subscribe 以及 channel,其分别表示执行订阅以及订阅的频道。
integer 1 表示订阅成功。
message 表示接收到的消息,之后出现的 channel 表示订阅频道,后面就是消息数据。
订阅成功之后,客户端会一直保持订阅状态,直到手动取消订阅或连接断开。
到此为止,一个基于 Redis 简单的发布/订阅模型就成功实现了。
它支持消费者阻塞式拉取消息,另外还提供了匹配订阅,消费者可以根据一定的规则,订阅多个队列。
例如subscribe mianshiya.*,此时如果生产者发布了 mianshiya.1、mianshiya.2、mianshiya.3 等队列的消息,消费者都可以接收到。
命令汇总:
- SUBSCRIBE channel:用于订阅某个频道。
- PUBLISH channel message:用于向某个频道发布消息。
- UNSUBSCRIBE channel:取消订阅某个频道。
- PSUBSCRIBE pattern:支持使用模式匹配订阅(如通配符*)来动态地订阅多个频道。
Redis 发布/订阅模型的原理
Redis 是如何实现这个功能的呢?实际上很简单。
消费者订阅队列,实际上就是在 Redis 中保存了一个映射关系,即队列 x -> 消费者 1。
如果生产者往这个队列 x 发送一条消息,Redis 不会做任何的存储动作,而是查找映射关系,然后立马转发给消费者1,所以 Redis 实际上就是提供了一个“转发通道”。如果找到多个映射关系,那么就都转发,所以支持多消费者的实现。
因此,不论是 rdb 还是 aof 都不会存储消息。
Redis 发布/订阅模型的缺点
会丢数据!
从原理我们就可以得知,Redis 并不会存储消息,那么如果生产者发布消息的时候,消费者宕机了,当服务恢复时,其间生产者发送的消息就丢失了。
不仅是宕机会导致消息丢失,如果消费者消费过慢也有可能导致消息丢失。
在面试鸭《651. Redis 主从复制的实现原理是什么? 》这题中,提到了 client-output-buffer-limit 参数,默认 pubsub 配置的是 32mb 8mb 60,即缓冲区一旦超过 32 MB 或持续 60s 超过 8M 直接把消费者下线。
Redis 虽然不会存储消息,但是消息会先写入这个缓冲区,供消费者拉取消费。如果消费者处理太慢,导致这个缓冲区溢出,那么消费者被强行下线,消息也就丢了。
Redis 发布/订阅模型应用场景
Redis 的哨兵集群和 Redis 实例通信用的就是发布/订阅模型。
一般业务上的即时通信场景也可以使用,但是由于消息会丢失,大部分情况下还是会使用消息队列中间件来实现发布/订阅。