參考文獻
15天玩轉redis —— 第九篇 發布/訂閱模式
《redis設計與實現》
psubscribe
publish
pubsub
punsubscribe
subscribe
unsubscribe
接下來一一簡述下這個6個命令的相關使用。
subscribe channel [channel ...]
訂閱給定的乙個或多個頻道的資訊。
subscribe命令可以訂閱乙個頻道。當有任何乙個客戶端向這個頻道推送訊息的時候,訂閱了這個頻道的客戶端都可以收到資料。
如上所述,客戶端可以訂閱乙個頻道的訊息,那麼我是否可以訂閱滿足一定條件的頻道的所有訊息呢?redis提供了psubscribe命令,這個命令可以訂閱符合模式的頻道的訊息。每個模式以 * 作為匹配符,比如 it* 匹配所有以 it 開頭的頻道( it.news 、 it.blog 、 it.tweets 等等), news.* 匹配所有以 news. 開頭的頻道( news.it 、 news.global.today 等等),諸如此類。
psubscribe pattern [pattern ...]
我訂閱了乙個頻道,也有需求退訂。unsubscribe命令就提供了客戶端退訂乙個渠道的功能。
unsubscribe [channel [channel ...]]
同理,如果我通過某個模式訂閱了頻道,我今天有點小後悔想退訂這個模式咋辦?使用punsubscribe命令就可以達成這個功能。
publish命令可以向乙個頻道推送訊息。如上面說到的,如果使用publish命令向乙個頻道推送訊息,則所有訂閱了這個頻道的客戶端都可以收到這個訊息。
publish channel message
上面都是關於訂閱和退訂相關的功能的簡述。如果我是管理redis的乙個dba,需要檢視當前有多少個活躍的頻道(活躍頻道指的是那些至少有乙個訂閱者的頻道),每個頻道有多少的訂閱者,有多少模式訂閱的相關資訊怎麼辦呢?redis給我們提供了pubsub命令。
pubsub [argument [argument ...]]
pubsub channels [pattern]:列出當前的活躍頻道。活躍頻道指的是那些至少有乙個訂閱者的頻道,訂閱模式的客戶端不計算在內。
pattern 引數是可選的:pubsub numsub [channel-1 ... channel-n] : 返回給定頻道的訂閱者數量,訂閱模式的客戶端不計算在內。如果不給出 pattern 引數,那麼列出訂閱與發布系統中的所有活躍頻道。
如果給出 pattern 引數,那麼只列出和給定模式 pattern 相匹配的那些活躍頻道。
pubsub numpat : 返回訂閱模式的數量。注意,這個命令返回的不是訂閱模式的客戶端的數量,而是客戶端訂閱的所有模式的數量總和。
前面的篇幅主要介紹了redis提供的發布和訂閱功能,接下來將介紹下發布和訂閱功能具體是怎麼實現的。
當你在redis客戶端鍵入subscribe的時候,就會建立乙個客戶端與乙個頻道的訂閱關係。那麼redis是通過怎樣的形式來完成這個關聯的呢?在redis中,將所有的頻道和客戶端的訂閱關係都儲存在乙個叫puhsub_channels的字典中。這個字典的key是是某個頻道,而values則是乙個鍊錶,記錄了所有訂閱這個頻道的客戶端。
struct redisserver
因此當建立乙個客戶端和頻道的訂閱關係的時候,大體會經歷如下的兩步操作:
如果該頻道已經存在於pubsub_channels中,則將客戶端加到這個鍊錶的後面。
如果這個頻道不存在,則在字典中建立乙個新的頻道,然後將客戶端新增到鍊錶中。
退訂的操作則和訂閱的操作相反:
根據退訂的頻道是哪個,將鍊錶上對應的客戶端刪除。
如果刪除了客戶端之後,整個鍊錶為空,則表示這個頻道沒有被訂閱,因此這個頻道也將被刪除 。
前面的部分說到了一般的訂閱和退訂,接下來將介紹redis模式的訂閱是如何實現的。在redis中所有的模式的訂閱的關係都儲存在伺服器的pubsub_patterns 屬性中。這個屬性是乙個鍊錶結構。
struct redisserver
鍊錶結構中每乙個節點都包含了乙個pubsub_pattern 結構。
typedef struct pubsubpattern pubsubpattern;
當客戶端執行模式的訂閱命令的時候,伺服器會執行以下的幾個操作:
新建乙個pubsubpattern,將結構的pattern設定為被訂閱的模式,client設定為訂閱這個模式的客戶端。
然後將這個結構體掛到pubsub_patterns的尾部。
退訂的操作則剛好相反:
遍歷pubsub_pattern,找到客戶端退訂的模式,將這個鍊錶的節點刪除
如前面的章節所述,頻道的訂閱是通過pubsub_channels結構實現的。那麼當推送乙個訊息給頻道的訂閱者的時候,則需要執行如下的幾個操作:
根據頻道的名稱在dict pubsub_channels中找到對應的頻道
遍歷這個頻道上所有的訂閱者名單,將資訊挨個傳送給訂閱者
那麼模式的訂閱的訊息傳送是如何實現的呢?其實實現的原理就更簡單了,redis會遍歷pubsub_patterns上所有的鍊錶節點,找到匹配的模式,然後傳送訊息。
Redis 發布和訂閱
發布與訂閱 又稱pub sub 訂閱者 listener 負責訂閱頻道 channel 傳送者 publisher 負責向頻道傳送二進位制字串訊息 binary string message 每當有訊息被傳送給指定頻道的時候,頻道都所有訂閱者都會收到訊息。redis提供都5個發布訂閱命令 命令描述 ...
Redis 發布和訂閱
一 概述 1 發布和訂閱是一種訊息通訊模式。2 優點 使訊息訂閱者和訊息發布者耦合度降低,類似設計模式中的觀察者模式。二 發布和訂閱 訂閱命令 訂閱乙個或多個頻道 返回值 value 1 為 subcribe 表示訂閱成功,value 2 為訂閱的頻道名稱,value 3 表示當前訂閱的頻道個數 s...
Java實現Redis發布訂閱
jedis使用指南 簡介 redis提供了基於 發布 訂閱 模式的訊息機制,此種模式下,訊息發布者和訂閱者不進行直接通訊,發布者客戶端向指定的頻道 channel 發布訊息,訂閱該頻道的每個客戶端都可以收到該訊息 頻道沒有 建立 的概念,可以直接訂閱 亦可直接發布訊息 下圖展示了頻道 channel...