Table of Contents generated with DocToc
Redis的发布与订阅功能由PUBLISH
、SUBSCRIBE
、PSUBSCRIBE
等命令组成。
通过执行SUBSCRIBE
命令,客户端可以订阅一个或多个频道,成为这些频道的订阅者(subscriber):每当有其他客户端向被订阅的频道发送消息时,频道的所有订阅者都会收到这条消息。
客户端还可以通过PSUBSCRIBE
订阅一个或多个模式:每当有其他客户端向某个频道发送消息,消息不仅会发送给这个频道的订阅者,还会发送给与这个频道相匹配的模式的订阅者。
Redis将所有频道的订阅关系都保存在服务器状态的pubsub_channles
字典中,键是某个被订阅的频道,值是一个链表,里面记录了所有订阅这个频道的客户端:
struct redisServer {
dict *pubsub_channels;
};
每当客户端执行SUBSCRIBE
命令时,服务器都会将客户端与被订阅的频道在pubsub_channles
字典中关联:
- 如果频道已有其他订阅者,将当前客户端添加到订阅者链表的末尾。
- 如果频道未有订阅者,则在
pubsub_channles
字典中创建一个键,并将客户端添加至链表。
UNSUBSCRIBE
命令让客户端退订某个频道,服务器从pubsub_channles
字典中解除关联:
- 根据被退订频道的名字,在
pubsub_channles
字典中找到订阅者链表,移除退订客户端的信息。 - 如果链表变成了空,则从
pubsub_channles
字典中删除频道对应的键。
服务器将所有模式订阅关系保存在pubsub_patterns
属性中:
struct redisServer {
list *pubsub_patterns;
};
pubsub_patterns
属性是个链表,每个节点都包含一个pubsubPattern
结构:
typedef struct pubsubPattern {
// 订阅模式的客户端
redisClient *client;
// 被订阅的模式
robj *pattern;
} pabsubPattern;
客户端执行PSUBSCRIBE
订阅某个模式时,服务器会对被订阅的模式执行以下操作:
- 新建一个
pubsubPattern
结构,初始化pattern
和client
值。 - 将
pubsubPattern
结构添加到pubsub_patterns
链表末尾。
客户端执行PUNSUBSCRIBE
退订某些模式的时候,服务器在pubsub_patterns
链表中查找并删除那些pattern
属性为被退订模式,且client
属性为执行退订命令的客户端的节点。
Redis客户端执行PUBLISH <channel> <message>
命令,将消息发送给频道时,服务器执行以下两个操作:
- 将
message
消息发送给channel
频道的所有订阅者。 - 如果一个或多个模式
pattern
与频道channel
匹配,那么将消息message
发送给pattern
模式的订阅者。
在pubsub_channles
字典中找到频道channel
的订阅者名单,然后将消息发送给名单中的所有客户端。
遍历整个pubsub_patterns
链表,查找那些与channel
频道相匹配的模式,然后将消息发送给订阅了这些模式的客户端。
PUBSUB
命令可以查看频道或模式的相关信息。
PUBSUB CHANNELS [pattern]
用于返回服务器当前被订阅的频道,其中pattern
参数可选。这个命令遍历pubsub_channles
字典的所有键,然后记录并返回符合条件的频道。
PUBSUB NUMSUB [channel-1 channel-2 … channel-N]
返回这些频道的订阅者的数量,也是在pubsub_channles
字典中找到频道对应的订阅者链表,然后返回链表的长度。
PUBSUB NUMPAT
返回服务器当前被订阅的模式的数量,返回pubsub_patterns
链表的长度。
上一章:17、集群
下一章:19、事务