Redis 通過 PUBLISH 、 SUBSCRIBE 等命令實現(xiàn)了訂閱與發(fā)布模式,這個功能提供兩種信息機制,分別是訂閱/發(fā)布到頻道和訂閱/發(fā)布到模式,下文先討論訂閱/發(fā)布到頻道的實現(xiàn),再討論訂閱/發(fā)布到模式的實現(xiàn)。
Redis 的 SUBSCRIBE 命令可以讓客戶端訂閱任意數(shù)量的頻道,每當(dāng)有新信息發(fā)送到被訂閱的頻道時,信息就會被發(fā)送給所有訂閱指定頻道的客戶端。
作為例子,下圖展示了頻道 channel1
,以及訂閱這個頻道的三個客戶端 —— client2
、 client5
和 client1
之間的關(guān)系:
channel1 [label = "subscribe"]; client5 -> channel1 [label = "subscribe"]; client1 -> channel1 [label = "subscribe"];}" />
當(dāng)有新消息通過 PUBLISH 命令發(fā)送給頻道 channel1
時,這個消息就會被發(fā)送給訂閱它的三個客戶端:
![digraph send_message_to_subscriber { node [style = filled]; edge [style = "dashed, bold"]; message [label = "PUBLISH channel1 message", shape = plaintext, fillcolor = "#FADCAD"]; message -> channel1 [color = "#B22222]"]; channel1 [label = "channel1", fillcolor = "#A8E270"]; node [shape = box]; client2 [label = "client2", fillcolor = "#95BBE3"]; client5 [label = "client5", fillcolor = "#95BBE3"]; client1 [label = "client1", fillcolor = "#95BBE3"]; / client2 -> channel1 [label = "subscribe"]; client5 -> channel1 [label = "subscribe"]; client1 -> channel1 [label = "subscribe"]; / channel1 -> client2 [label = "message", color = "#B22222"]; channel1 -> client5 [label = "message", color = "#B22222"]; channel1 -> client1 [label = "message", color = "#B22222"];}]
在后面的內(nèi)容中,我們將探討 SUBSCRIBE 和 PUBLISH 命令的實現(xiàn),以及這套訂閱與發(fā)布機制的運作原理。
每個 Redis 服務(wù)器進程都維持著一個表示服務(wù)器狀態(tài)的 redis.h/redisServer
結(jié)構(gòu),結(jié)構(gòu)的 pubsub_channels
屬性是一個字典,這個字典就用于保存訂閱頻道的信息:
struct redisServer {
// ...
dict *pubsub_channels;
// ...
};
其中,字典的鍵為正在被訂閱的頻道,而字典的值則是一個鏈表,鏈表中保存了所有訂閱這個頻道的客戶端。
比如說,在下圖展示的這個 pubsub_channels
示例中, client2
、 client5
和 client1
就訂閱了 channel1
,而其他頻道也分別被別的客戶端所訂閱:
更多建議: