1. 程式人生 > 其它 >《Redis設計與實現》讀書筆記(三十二) ——Redis集釋出訂閱設計與實現

《Redis設計與實現》讀書筆記(三十二) ——Redis集釋出訂閱設計與實現

《Redis設計與實現》讀書筆記(三十二) ——Redis集釋出訂閱設計與實現

(原創內容,轉載請註明來源,謝謝)

一、概述

redis的釋出訂閱由publish、subscribe、psubscribe等命令組成。客戶端通過subscribe訂閱頻道,釋出端通過publish進行釋出。

例如,a、b、c三個客戶端都執行了命令subscribe“new.it”,則表示這三個客戶端都監聽該頻道的資訊。此時,如果某個客戶端執行publish “new.it” “hello”,則a、b、c三個客戶端都會收到該訊息。

每個客戶端都可以訂閱多個頻道,每個頻道也可以給多個客戶端訂閱,屬於多對多關係。

如上圖所示,當訊息發到news.it頻道,則a、c、d三個客戶端都會收到訊息。

二、頻道訂閱與退訂

1、訂閱

當客戶端執行subscribe命令,客戶端和頻道之間就形成訂閱的關係,redis將所有頻道的訂閱關係放在redisServer結構體的pubsub_channels字典中,這個字典的鍵是被訂閱的頻道,值是連結串列,連結串列裡面記錄了所有訂閱這個頻道的客戶端。

每當有客戶端訂閱頻道,伺服器都會將字典中的頻道與客戶端關聯。如果頻道已經有其他訂閱者,則該客戶端加到連結串列的末尾;如果頻道還沒有訂閱者,則不存在於pubsub_channels字典,則會新建立一個鍵值對。

2、退訂

unsubscribe命令是退訂的命令,客戶端執行此命令退訂某個頻道,則伺服器會將鍵對應的連結串列的節點刪除。另外,如果刪除連結串列的節點後,該頻道的鍵對應的連結串列是空,表示此時沒有客戶端定義該頻道,則該鍵也會被刪除。

三、模式的訂閱與退訂

1、訂閱模式

模式的訂閱與退訂儲存在redisServer結構體的列表pubsub_patterns中,該list是一個連結串列,每個節點包含一個pubsub_pattern結構,如下:

         typedef struct pubsubPattern{
                  redisClient *client;
                  robj *pattern;
         }pubsubPattern;

這個結構的pattern記錄了訂閱的模式,而client記錄了定閱該模式的客戶端。

當客戶端執行psubscribe命令,即訂閱某個模式,redis伺服器會新建一個pubsubPattern節點,並且將client資訊進行記錄。

2、退訂模式

punsubscribe命令是退訂模式的命令。當退訂模式,伺服器會將客戶端的資訊從模式對應的pubsubPattern結構體刪除。

四、傳送訊息

redis任一客戶端執行publish <channel><message>,表示其傳送訊息,其會將訊息傳送給頻道訂閱者與模式訂閱者。

1、傳送給頻道訂閱者

由於pubsub_channels字典記錄所有頻道的訂閱關係,則redis伺服器會從頻道的字典中,找到channel訂閱者的名單,即一個連結串列,並將訊息傳送給其中的所有的訂閱者。

2、傳送給模式訂閱者

由於pubsub_patterns是一個連結串列形式,記錄所有的模式訂閱者的資訊,因此redis會遍歷該連結串列,找到所有與當前channel匹配的模式,並將訊息傳送給這些模式的客戶端。

五、檢視訂閱資訊

pubsub命令可以用於檢視頻道的訂閱情況,其共有三個子命令。

1、pubsubchannels

pubsub channels [pattern]命令用於返回伺服器當前被訂閱的頻道,pattern引數可選,不給定引數,返回當前所有頻道;給定引數,返回當前頻道中與pattern模式匹配的頻道。

該命令是通過遍歷pubsub_channels字典,檢視所有匹配的頻道。

2、pubsubnumsub

pubsub numsub [channel-1 channel-2 …]子命令接收多個頻道作為引數,返回這些頻道訂閱者的數量。

該命令是通過遍歷pattern_channels字典,找到需要查閱的頻道,並且返回頻道對應的連結串列的長度。如果頻道沒有被訂閱,則返回0。

3、pubsubnumpat

pubsub numpat返回伺服器當前被訂閱的模式的數量。

該命令是通過返回pubsub_patterns連結串列的長度來實現的。

六、總結

1、訂閱分為頻道訂閱和模式訂閱。伺服器在redisServer結構體的字典pubsub_channels中,以鍵作為頻道名稱,值是所有訂閱該頻道的連結串列;在連結串列pubsub_patterns中,記錄所有被訂閱的模式以及對應的客戶端資訊。

2、頻道訂閱與退訂命令分別是subscribe、unsubscribe,模式訂閱與退訂命令分別是psubscribe、punsubscribe,釋出命令是publish。

3、publish命令通過訪問pubsub_channel來找到頻道訂閱者,通過pubsub_patterns找到模式訂閱者,並且傳送訊息。

——written by linhxx 2017.09.26