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