redis的發布與訂閱功能由publish、subscribe、psubscribe等命令組成。
通過執行subscribe命令,客戶端可以訂閱乙個或多個頻道,從而成為這些頻道的訂閱者(subscriber):每當有其他客戶端向被訂閱的頻道傳送訊息(message)時,頻道的所有訂閱者都會收到這個訊息。
除了訂閱頻道之外,客戶端還可以通過執行psubscribe命令訂閱乙個或多個模式,從而成為這些模式的訂閱者:每當有其他客戶端向某個頻道傳送訊息時,訊息不僅會被傳送給這個頻道的所有訂閱者,它還會被傳送給所有與這個頻道相匹配的模式的訂閱者
1. 頻道的訂閱與退訂
當乙個客戶端執行subscribe命令訂閱某個或某些頻道的時候,這個客戶端與被訂閱頻道之間就建立起了一種訂閱關係。
redis將所有頻道的訂閱關係都儲存在伺服器狀態的pubsub_channels字典裡面,這個字典的鍵是某個被訂閱的頻道,而鍵的值則是乙個鍊錶,鍊錶裡面記錄了所有訂閱這個頻道的客戶端:
struct redisserver ;
1.1 訂閱頻道
每當客戶端執行subscribe命令訂閱某個或某些頻道的時候,伺服器都會講客戶端與被訂閱的頻道在pubsub_channels字典中進行關聯。
根據頻道是否已經有其他訂閱者,關聯操作分為兩種情況執行:
1)如果有,那麼字典中必然有相應的訂閱者鍊錶,那麼將客戶端新增到訂閱者鍊錶的末尾
2)如果沒有,那麼首先在字典中為頻道建立乙個鍵,並將這個鍵的值設定為空鍊錶,再將客戶端新增到鍊錶,成為第乙個元素。
1.2 退訂頻道
unsubscribe命令的行為和subscribe命令的行為正好相反,當乙個客戶端退訂某個或某些頻道的時候,伺服器將從pubsub_channels中解除客戶端與被退訂頻道之間的關聯:
1)程式根據被退訂頻道的名字,在pubsub_channels字典中找到頻道對應的訂閱者鍊錶,然後刪除退訂客戶端的資訊
2)如果刪除退訂客戶端之後,頻道的訂閱者鍊錶變成了空鍊錶,那麼將從pubsub_channels字典中刪除頻道對應的鍵
2. 模式的訂閱與退訂
伺服器將所有頻道的訂閱關係都儲存在伺服器狀態的pubsub_channels屬性裡,與此類似,伺服器將所有模式的訂閱關係都儲存在pubsub_patterns屬性裡:
struct redisserver;
pubsub_patterns屬性是乙個鍊錶,鍊錶中的每個節點都包含著乙個pubsubpattern結構,這個結構的pattern屬性記錄了被訂閱的模式,而client屬性則記錄了訂閱模式的客戶端:
typedef struct pubsubpattern pubsubpattern;
2.1 訂閱模式
每當客戶端執行psubscribe命令訂閱某個或某些模式的時候,伺服器會對每個被訂閱的模式執行以下操作:
1)新建乙個pubsubpattern結構,將結構的pattern屬性設定為被訂閱的模式,client屬性設定為訂閱模式的客戶端
2)將pubsubpattern結構新增到pubsub_patterns鍊錶的表尾
2.2 退訂模式
模式的退訂命令punsubscribe是psubscribe命令的反操作:當乙個客戶端退訂某個或某些模式的時候,伺服器在pubsub_patterns鍊錶中查詢並刪除那些pattern屬性為被退訂模式,並且client屬性為執行退訂命令的客戶端的pubsubpattern結構。
3.傳送訊息
當乙個redis客戶端執行publish 命令將訊息message傳送給頻道channel的時候,伺服器需要執行以下兩個動作:
1)將訊息message傳送給channel頻道的所有訂閱者
2)如果乙個或多個pattern與頻道channel相匹配,那麼將訊息message傳送給pattern模式的訂閱者
3.1將訊息傳送給頻道訂閱者
因為伺服器狀態中的pubsub_channels字典記錄了所有頻道的訂閱關係,所以為了將訊息傳送給channel頻道的所有訂閱者,publish命令要做的就是在pubsub_channels字典裡找到頻道channel的訂閱者名單(乙個鍊錶),然後將訊息傳送給名單上的所有客戶端。
3.2 將訊息傳送給模式訂閱者
因為伺服器狀態中的pubsub_patterns鍊錶記錄了所有模式的訂閱關係,所以為了將訊息傳送給channel頻道相匹配的模式的訂閱者,publish命令要做的就是遍歷整個pubsub_patterns鍊錶,查詢那些與channel頻道相匹配的模式,並將訊息傳送給訂閱了這些模式的客戶端
4. 檢視訂閱資訊
pubsub命令是redis2.8新增加的命令之一,客戶端可以通過這個命令來檢視頻道或者模式的相關資訊。
4.1 pubsub channels
pubsub channels 子命令用於返回伺服器當前被訂閱的頻道,其中pattern引數是可選的:
1)如果不給定,那麼返回被訂閱的所有頻道
2)給定,那麼返回被訂閱的頻道中那些與pattern模式相匹配的頻道
這個子命令是通過遍歷伺服器pubsub_channels字典的所有鍵,然後記錄並返回所有符合條件的頻道來實現。
4.2 pubsub numsub
pubsub numsub [channel-1 channel-2 ... channel-n]子命令接收任意多個頻道作為輸入引數,並返回這些頻道的訂閱者數量。
這個子命令是通過在pubsub_channels字典中找到頻道對應的訂閱者鍊錶,然後返回訂閱者鍊錶的長度來實現
4.3 pubsub numpat
pubsub numpat子命令用於返回伺服器當前被訂閱模式的數量
這個子命令是通過返回pubsub_patterns鍊錶長度來實現的,因為這個鍊錶的長度就是伺服器被訂閱模式的數量
10 發布訂閱模型
icestorm 是乙個高效的用於ice應用的發布 訂閱服務,icestorm有幾個比較重要的概念 訊息 icestorm的訊息和普通的訊息佇列中介軟體中描述的訊息有點區別,icestorm 的訊息是強型別的,由對某個slice 操作的呼叫 代表 操作名 標識 訊息的型別,操作引數 定義 訊息內容。...
redis 二 發布訂閱
參考資料 redis 4.x cookbook 中文版 redis官方文件 注 本文redis的版本為 5.0.3 注意,如果先發布訊息,然而頻道沒有訂閱者,這時的訊息會被丟失 redis的發布訂閱是乙個訊息推送的機制 發布者 publisher 向指定頻道 channel 發布訊息 message...
3 1 7 發布訂閱模式
發布訂閱模式和觀察者模式是兩種設計模式,在 vue 中有各自的應用場景。兩種模式的本質是相同的,但是還是有區別的,經常被混為一談。我們假定,存在乙個 訊號中心 某個任務執行完畢,就向訊號中心 發布 publish 乙個訊號,其他任務可以向訊號中心 訂閱 subscribe 這個訊號,從開知道什麼時候...