本文主要说明Redis中发布与订阅功能的设计与实现。
I、上帝视角看发布于订阅
Redis主要通过PUBLISH
,SUBSCRIBE
,PSUBSCRIBE
命令实现发布于订阅功能。
1、 客户端通过执行SUBSCRIBE
命令,订阅一个或多个频道:每当有其他客户端向被订阅频道发送消息时,频道的所有订阅者都会受到这条消息。
2、客户端通过执行PUBLISH
命令发布消息:
PUBLISH "news.it" "hello"
向news.it频道发送“hello”消息,则三个订阅者都会收到“hello”。
3、 客户端还可以通过PSUBSCRIBE
命令订阅一个或多个模式:每当有其他客户端向某个频道发送消息时,消息不仅会被发送到这个频道的订阅者,还会发送到与这个频道相匹配的模式的订阅者。
II、频道的订阅与退订
当一个客户端执行SUBSCRIBE
命令订阅某个或某些频道时,客户端与被订阅频道之间就建立了一种订阅关系。
Redis将所有频道的订阅关系都保存到服务器状态的pubsub_channels字典中,这个字典的键为某个订阅的频道,值为一个链表,这个链表记录了所有订阅此频道的客户端:
struct redisServer {
//保存所有频道的订阅关系
dict *pubsub_channels;
};
下图展示了这种字典结构:
客户端可以通过UNSBUSCRIBE
命令退订某个频道。
III、模式的订阅与退订
服务器将所有模式的订阅关系都保存到服务器状态的pubsub_patterns属性中,pubsub_patterns属性是一个链表,链表中每个节点都包含一个pubsub_Parten结构,这个结构的pattern属性记录了被订阅的模式,而client属性积累了订阅模式的客户端:
typedef struct pubsubPattern {
//订阅模式的客户端
redisClient * client;
//被订阅的模式
robj *pattern;
} pubsubPattern;
下图描述了这个模式订阅结构:
模式的退订命令由PUNSUBSCRIBE
执行。
IV、PUBLISH
Redis客户端执行PUBLISH <channel> <message>
命令将message消息发送给频道channel的时候,服务器会执行两个操作:
· 将message发送给channel频道的所有订阅者;
· 如果有pattern与channel匹配,则将message发送给所有pattern的订阅者。
4.1 查看订阅信息
1、PUBSUB CHANNELS [pattern]
子命令用于返回服务器当前被订阅的频道,其中pattern为可选参数:
· 如果不给定pattern参数,则返回服务器当前订阅的所有频道;
· 如果给定pattern参数,那么返回服务器当前被订阅的频道中与pattern相匹配的频道。
2、PUBSUB NUMSUB [channel-1 channel-2 ... channel-n]
子命令接受任意多个频道作为输入参数,并返回这些频道的订阅者数量。
3、PUBSUB NUMPAT
子命令用于返回服务器当前被订阅模式的数量。
【参考】
[1] 《Redis设计与实习》
欢迎转载,转载请注明出处wenmingxing Redis之发布与订阅