本节概览:介绍redis pub/sub命令使用和原理。

本文内容来自 https://redisbook.readthedocs.io/en/latest/feature/pubsub.html

1 命令介绍

Snip20210527_231

Redis 的 SUBSCRIBE 命令可以让客户端订阅任意数量的频道, 每当有新信息发送到被订阅的频道时, 信息就会被发送给所有订阅指定频道的客户端。 发送的消息不会保存在Redis服务器里面,所以如果接收消息客户端断连,则会丢失消息。

下图展示了频道 channel1 , 以及订阅这个频道的三个客户端 client2 、 client5 和 client1 之间的关系:

1

当有新消息通过 PUBLISH 命令发送给频道 channel1 时, 这个消息就会被发送给订阅它的三个客户端:

Snip20210527_232

命令举例

1

2 实现

2.1 数据结构

每个 Redis 服务器进程都维持着一个表示服务器状态的 redis.h/redisServer 结构, 结构的 pubsub_channels 属性是一个字典, 这个字典就用于保存订阅频道的信息,字典的键为正在被订阅的频道, 而字典的值则是一个链表, 链表中保存了所有订阅这个频道的客户端。

比如说,在下图展示的这个 pubsub_channels 示例中, client2 、 client5 和 client1 就订阅了 channel1 , 而其他频道也分别被别的客户端所订阅:

Snip20210527_233

2.2 SUBSCRIBE

当客户端调用 SUBSCRIBE 命令时,程序就将客户端和要订阅的频道在 pubsub_channels 字典中关联起来。如客户端 client10086 执行命令 SUBSCRIBE channel1 channel2 channel3 ,那么前面展示的 pubsub_channels 将变成下面这个样子:

Snip20210527_234

伪代码如下

2.3 PUBLISH命令

PUBLISH 命令的实现就非常简单了: 当调用 PUBLISH channel message 命令, 程序首先根据 channel 定位到字典的键, 然后将信息发送给字典值链表中的所有客户端。

比如说,对于以下这个 pubsub_channels 实例, 如果某个客户端执行命令 PUBLISH channel1 "hello moto" ,那么 client2 、 client5 和 client1 三个客户端都将接收到 "hello moto" 信息。

Snip20210527_233

伪代码如下

 

分类&标签