本文主要說明Redis中發(fā)布與訂閱功能的設(shè)計與實現(xiàn)逻锐。
I摔刁、上帝視角看發(fā)布于訂閱
Redis主要通過PUBLISH
,SUBSCRIBE
个少,PSUBSCRIBE
命令實現(xiàn)發(fā)布于訂閱功能蒙揣。
1靶溜、 客戶端通過執(zhí)行SUBSCRIBE
命令,訂閱一個或多個頻道:每當有其他客戶端向被訂閱頻道發(fā)送消息時懒震,頻道的所有訂閱者都會受到這條消息罩息。
2、客戶端通過執(zhí)行PUBLISH
命令發(fā)布消息:
PUBLISH "news.it" "hello"
向news.it頻道發(fā)送“hello”消息个扰,則三個訂閱者都會收到“hello”瓷炮。
3、 客戶端還可以通過PSUBSCRIBE
命令訂閱一個或多個模式:每當有其他客戶端向某個頻道發(fā)送消息時递宅,消息不僅會被發(fā)送到這個頻道的訂閱者娘香,還會發(fā)送到與這個頻道相匹配的模式的訂閱者冬筒。
II、頻道的訂閱與退訂
當一個客戶端執(zhí)行SUBSCRIBE
命令訂閱某個或某些頻道時茅主,客戶端與被訂閱頻道之間就建立了一種訂閱關(guān)系。
Redis將所有頻道的訂閱關(guān)系都保存到服務器狀態(tài)的pubsub_channels字典中土榴,這個字典的鍵為某個訂閱的頻道诀姚,值為一個鏈表,這個鏈表記錄了所有訂閱此頻道的客戶端:
struct redisServer {
//保存所有頻道的訂閱關(guān)系
dict *pubsub_channels;
};
下圖展示了這種字典結(jié)構(gòu):
客戶端可以通過UNSBUSCRIBE
命令退訂某個頻道玷禽。
III赫段、模式的訂閱與退訂
服務器將所有模式的訂閱關(guān)系都保存到服務器狀態(tài)的pubsub_patterns屬性中,pubsub_patterns屬性是一個鏈表矢赁,鏈表中每個節(jié)點都包含一個pubsub_Parten結(jié)構(gòu)糯笙,這個結(jié)構(gòu)的pattern屬性記錄了被訂閱的模式,而client屬性積累了訂閱模式的客戶端:
typedef struct pubsubPattern {
//訂閱模式的客戶端
redisClient * client;
//被訂閱的模式
robj *pattern;
} pubsubPattern;
下圖描述了這個模式訂閱結(jié)構(gòu):
模式的退訂命令由PUNSUBSCRIBE
執(zhí)行撩银。
IV给涕、PUBLISH
Redis客戶端執(zhí)行PUBLISH <channel> <message>
命令將message消息發(fā)送給頻道channel的時候,服務器會執(zhí)行兩個操作:
· 將message發(fā)送給channel頻道的所有訂閱者额获;
· 如果有pattern與channel匹配够庙,則將message發(fā)送給所有pattern的訂閱者。
4.1 查看訂閱信息
1抄邀、PUBSUB CHANNELS [pattern]
子命令用于返回服務器當前被訂閱的頻道耘眨,其中pattern為可選參數(shù):
· 如果不給定pattern參數(shù),則返回服務器當前訂閱的所有頻道境肾;
· 如果給定pattern參數(shù)剔难,那么返回服務器當前被訂閱的頻道中與pattern相匹配的頻道。
2奥喻、PUBSUB NUMSUB [channel-1 channel-2 ... channel-n]
子命令接受任意多個頻道作為輸入?yún)?shù)偶宫,并返回這些頻道的訂閱者數(shù)量。
3衫嵌、PUBSUB NUMPAT
子命令用于返回服務器當前被訂閱模式的數(shù)量读宙。
【參考】
[1] 《Redis設(shè)計與實習》
歡迎轉(zhuǎn)載,轉(zhuǎn)載請注明出處wenmingxing Redis之發(fā)布與訂閱