Redis訂閱與發布


 發布與訂閱模型在許多編程語言中都有實現,也就是我們經常說的設計模式中的一種--觀察者模式。在一些應用場合,例如發送方並不是以固定頻率發送消息,如果接收方頻繁去咨詢發送方,這種操作無疑是很麻煩並且不友好的。

舉個生活的例子,一個喜歡購買鮮牛奶的人,需要每天在上班的時候/下班的時候都專門去牛奶店購買鮮牛奶,但不一定每天去到那里都剛好有自己喜歡的那一種牛奶,這個時候,這個人跑老遠的距離都白費了。但如果這個人去牛奶店一次性訂閱了一個月的某種牛奶,那么他就不用擔憂今天是否能買到鮮牛奶了,只要送奶員把牛奶送到他家樓下的箱子里面就行。

而訂閱發布模型與這個例子有點類似,訂閱者只要訂閱注冊某個頻道就可以“高枕無憂”了,當有消息發送過來的時候,會通過訂閱的頻道接收。優勢在於把耦合點獨立分離處理,作為發布方和接收方的中介,實現了發布方和接收方的隔離,

 

訂閱與發布系統是Redis的一個高級屬性,多個客戶端可以同時訂閱同一個頻道,類似廣播的機制。所不同的是,一個客戶端可以同時訂閱多個頻道。

樣例圖:

 

Redis訂閱發布系統,服務器在背后的工作:

服務器中維護着一個pubsub_channels字典,所有的頻道和訂閱關系都存儲在這里。字典的鍵為頻道的名稱,而值為訂閱頻道的客戶端鏈表。

1. 當有新的客戶端訂閱某個頻道時,會發生兩種情況中的一種:

1)如果頻道已經存在,則新的客戶端會添加到pubsub_channels對應頻道的鏈表末尾

2)如果頻道原本不存在,則會為頻道創建一個鍵,該客戶端成為鏈表的第一個元素

2. 當一個客戶端退訂一個頻道的時候:

pubsub_channels對應鍵的鏈表會刪除該客戶端

3. 發送信息

服務器會遍歷pubsub_channels中對應鍵的鏈表,向每一個客戶端發送信息

 

服務器還維護着一個pubsub_patterns鏈表,鏈表的pattern屬性記錄了被訂閱的模式,而client屬性記錄了訂閱模式的客戶端

1. 當有新的客戶端訂閱某個模式的時,會進行如下步驟:

1)創建一個鏈表節點,pattern屬性記錄訂閱的模式,client記錄訂閱模式的客戶端

2)將這個鏈表節點添加到pubsub_patterns鏈表中

2. 當一個客戶端退訂某一個模式的時候:

服務器遍歷pubsob_patterns找到對應的pattern同時也是對應該client客戶端的節點,將改節點刪除

3. 發送信息

服務器遍歷pubsub_channels,查找與channels頻道相匹配的模式麻將消息發送給訂閱了這些模式的客戶端。

 

Redis訂閱系統的優勢:

1. 當一個客戶端向頻道發送一個信息,訂閱了同一個頻道/模式的多個客戶端可以同時接收到信息,類似廣播的機制。

2. 便於Sentinel哨兵與服務器間的通信並進行監控

 

 

1. 訂閱頻道

命令格式:

SUSCRIBE   channel1  [channel2]  [channel3]

例如(同時訂閱兩個頻道):

redis> subscribe  local_system  remote_system

Reading messages... (press Ctrl-C to quit)

1) "subscribe"       # 返回值的類型:顯示訂閱成功

2) "local_system"           # 訂閱的頻道名字

3)"remote _system "

4) (integer) 2       # 目前已訂閱的頻道數量

 

訂閱和接收者:

發送者:

 

 

注意:客戶端一點與某個頻道建立連接就不能進行其他操作,一旦客戶端退出連接,訂閱的頻道自動會斷開。

 

2. 訂閱模式

PSUBSCRIBE  pattern1  [pattern2]  [pattern3]

pattern可以用符號*進行模糊匹配,例如:

remo*   #匹配以remo開頭的模式

*system  #匹配以system結尾的模式

 

例如:

客戶端1

客戶端2

注意:返回的integer為1是指匹配了一個模式,實際上是匹配了兩個頻道。

 

發布信息命令:

客戶端:

 

 

3. 取消訂閱:

命令:

1)取消訂閱頻道

UNSUBSCRIBE  channel1  [channel2]

2)取消訂閱模式

PUNSUBSCRIBE  [pattern [pattern …]]

由於在客戶端界面無法實現,這里就不展示了。而在編程過程中是可以實現的。

關於python中的編程,可以看看這篇文章:

http://www.cnblogs.com/anpengapple/p/7027979.html

 

4. 發布消息

命令:

PUBLISH channel message

向一個頻道發送信息,所有訂閱這個頻道的客戶端都會接收到信息

 

5. 查看已有的頻道

命令:

PUBSUB  subcommand [argument [argument ...]]

subcommand子命令:

1)PUBSUB CHANNELS  [pattern]

列出當前的活躍頻道

如果給定pattern參數,則會返回服務器當前被訂閱的頻道中與pattern模式相匹配的頻道

 

2)PUBSUB NUMSUB [channel-1 … channel-N]

返回給定頻道的訂閱者數量, 訂閱模式的客戶端不計算在內

因為有一個是匹配模式,所以返回的interger值為1

 

3)PUBSUB NUMPAT

返回訂閱模式的數量

 

 

Sentinel哨兵中的應用:

Sentinel服務器與Master服務器/Slave服務器之間的訂閱發布系統是Sentinl監控過程的一個重要環節,通過訂閱發布系統達到監控服務器狀態的作用。其運行原理與上面的客戶端服務器之間的訂閱機制無太大區別,都是基於網絡連接的數據傳輸。Sentinel之間的通信也是通過Sentinel與服務武器間的這個訂閱發布系統實現的,一個Sentinel通過服務器的頻道發送信息,其他Sentinel就會接收到。

 

參考文章:

http://www.cnblogs.com/anpengapple/p/7027979.html

《redis設計與實現》

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM