前言:用了redis也有一段時間了,但是釋出與訂閱的使用頻率也不高,趁著這次空閒,深究下redis的釋出與訂閱模式。
一、訂閱頻道和資訊釋出
功能說明:Redis 的 SUBSCRIBE 命令可以讓客戶端訂閱任意數量的頻道, 每當有新資訊傳送到被訂閱的頻道時, 資訊就會被髮送給所有訂閱指定頻道的客戶端。
訂閱例子示意圖:下圖展示了頻道 channel1 , 以及訂閱這個頻道的三個客戶端 —— client2 、 client5 和 client1 之間的關係:
釋出例子示意圖:當有新訊息通過 PUBLISH 命令傳送給頻道 channel1 時, 這個訊息就會被髮送給訂閱它的三個客戶端:
二、訂閱頻道結構原理解析
說明:每個 Redis 伺服器程式都維持著一個表示伺服器狀態的 redis.h/redisServer 結構, 結構的 pubsub_channels 屬性是一個字典, 這個字典就用於儲存訂閱頻道的資訊,其中,字典的鍵為正在被訂閱的頻道, 而字典的值則是一個連結串列, 連結串列中儲存了所有訂閱這個頻道的客戶端。
例子示意圖:在下圖展示的這個 pubsub_channels
示例中, client2
、 client5
和 client1
就訂閱了 channel1
, 而其他頻道也分別被別的客戶端所訂閱。
操作:當客戶端呼叫 SUBSCRIBE 命令時, 程式就將客戶端和要訂閱的頻道在 pubsub_channels 字典中關聯起來。
示意圖:如果客戶端 client10086 執行命令 SUBSCRIBE channel1 channel2 channel3 ,那麼前面展示的 pubsub_channels 將變成下面這個樣子,通過遍歷所有輸入頻道。
結論:通過 pubsub_channels 字典, 程式只要檢查某個頻道是否為字典的鍵, 就可以知道該頻道是否正在被客戶端訂閱; 只要取出某個鍵的值, 就可以得到所有訂閱該頻道的客戶端的資訊。
三、釋出資訊到頻道結構解析
原理說明:當呼叫 PUBLISH channel message 命令, 程式首先根據 channel 定位到字典的鍵, 然後將資訊傳送給字典值連結串列中的所有客戶端。
例子示意圖:對於以下這個 pubsub_channels 例項, 如果某個客戶端執行命令 PUBLISH channel1 "hello moto" ,那麼 client2 、 client5 和 client1 三個客戶端都將接收到 "hello moto" 資訊,通過遍歷訂閱頻道的所有客戶端。
四、退訂頻道
原理:使用 UNSUBSCRIBE 命令可以退訂指定的頻道, 這個命令執行的是訂閱的反操作: 它從 pubsub_channels 字典的給定頻道(鍵)中, 刪除關於當前客戶端的資訊, 這樣被退訂頻道的資訊就不會再傳送給這個客戶端。
以上就是本篇文章的全部了,其中redis還有一種基於模式的訂閱與資訊傳送。帶後續補上。
參考連結:https://redisbook.readthedocs.io/en/latest/feature/pubsub.html