1. 程式人生 > >Redis釋出訂閱機制

Redis釋出訂閱機制

1. 什麼是Redis

Redis是一個開源的記憶體資料庫,它以鍵值對的形式儲存資料。由於資料儲存在記憶體中,因此Redis的速度很快,但是每次重啟Redis服務時,其中的資料也會丟失,因此,Redis也提供了持久化儲存機制,將資料以某種形式儲存在檔案中,每次重啟時,可以自動從檔案載入資料到記憶體當中。 
這裡寫圖片描述 
Redis的架構包括兩個部分:Redis Client和Redis Server。Redis客戶端負責向伺服器端傳送請求並接受來自伺服器端的響應。伺服器端負責處理客戶端請求,例如,儲存資料,修改資料等。 
Redis通常用作資料庫,快取以及訊息系統。

2. Redis釋出訂閱

2.1 Redis釋出訂閱架構

Redis提供了釋出訂閱功能,可以用於訊息的傳輸,Redis的釋出訂閱機制包括三個部分,釋出者,訂閱者和Channel。 
這裡寫圖片描述 
釋出者和訂閱者都是Redis客戶端,Channel則為Redis伺服器端,釋出者將訊息傳送到某個的頻道,訂閱了這個頻道的訂閱者就能接收到這條訊息。Redis的這種釋出訂閱機制與基於主題的釋出訂閱類似,Channel相當於主題。

2.2 Redis釋出訂閱功能

(1)傳送訊息 
Redis採用PUBLISH命令傳送訊息,其返回值為接收到該訊息的訂閱者的數量。 
這裡寫圖片描述 
(2)訂閱某個頻道 
Redis採用SUBSCRIBE命令訂閱某個頻道,其返回值包括客戶端訂閱的頻道,目前已訂閱的頻道數量,以及接收到的訊息,其中subscribe表示已經成功訂閱了某個頻道。 
這裡寫圖片描述

 
(3)模式匹配 
模式匹配功能允許客戶端訂閱符合某個模式的頻道,Redis採用PSUBSCRIBE訂閱符合某個模式所有頻道,用“”表示模式,“”可以被任意值代替。 
這裡寫圖片描述 
假設客戶端同時訂閱了某種模式和符合該模式的某個頻道,那麼傳送給這個頻道的訊息將被客戶端接收到兩次,只不過這兩條訊息的型別不同,一個是message型別,一個是pmessage型別,但其內容相同。 
(4)取消訂閱 
Redis採用UNSUBSCRIBE和PUNSUBSCRIBE命令取消訂閱,其返回值與訂閱類似。 
由 於Redis的訂閱操作是阻塞式的,因此一旦客戶端訂閱了某個頻道或模式,就將會一直處於訂閱狀態直到退出。在 SUBSCRIBE,PSUBSCRIBE,UNSUBSCRIBE和PUNSUBSCRIBE命令中,其返回值都包含了該客戶端當前訂閱的頻道和模式的 數量,當這個數量變為0時,該客戶端會自動退出訂閱狀態。

2.3 Redis釋出訂閱實現

由於Redis是一個開源的系統,因此我們可以通過其原始碼檢視內部的實現細節。 
(1)SUBSCRIBE 
這裡寫圖片描述 
當 客戶端訂閱某個頻道時,Redis需要將該頻道和該客戶端繫結。首先,在客戶端結構體client中,有一個屬性為pubsub_channels,該屬 性表明了該客戶端訂閱的所有頻道,它是一個字典型別,通過雜湊表實現,其中的每個元素都包含了一個鍵值對以及指向下一個元素的指標,每次訂閱都要向其中插 入一個結點,鍵表示訂閱的頻道,值為空。然後,在表示伺服器端的結構體redisServer中,也有一個屬性為pubsub_channels,但此處 它表示的是該伺服器端中的所有頻道以及訂閱了這個頻道的客戶端,它也是一個字典型別,插入結點時,鍵表示頻道,值則是訂閱了這個頻道的所有客戶端組成的鏈 表。最後Redis通知客戶端其訂閱成功。 
(2)PSUBSCRIBE 
這裡寫圖片描述 
當 客戶端訂閱某個模式時,Redis同樣需要將該模式和該客戶端繫結。首先,在結構體client中,有一個屬性為pubsub_patterns,該屬性 表示該客戶端訂閱的所有模式,它是一個連結串列型別,每個結點包括了訂閱的模式和指向下一個結點的指標,每次訂閱某個模式時,都要向其中插入一個結點。然後, 在結構體redisServer中,有一個屬性也叫pubsub_patterns,它表示了該伺服器端中的所有模式和訂閱了這些模式的客戶端,它也是一 個連結串列型別,插入結點時,每個結點都要包含訂閱的模式,以及訂閱這個模式的客戶端,和指向下一個結點的指標。 
(3)PUBLISH 
這裡寫圖片描述 
當 客戶端向某個頻道傳送訊息時,Redis首先在結構體redisServer中的pubsub_channels中找出鍵為該頻道的結點,遍歷該結點的 值,即遍歷訂閱了該頻道的所有客戶端,將訊息傳送給這些客戶端。然後,遍歷結構體redisServer中的pubsub_patterns,找出包含該 頻道的模式的結點,將訊息傳送給訂閱了該模式的客戶端。

2.4 Redis釋出訂閱在Redis中的應用

Redis的釋出訂閱功能與Redis中的資料儲存時無關的,它不會影響Redis的key space,即不會影響Redis中儲存的資料,但通過釋出訂閱機制,Redis還提供了另一個功能,即Keyspace Notification,允許客戶端通過訂閱特定的頻道,從而得知是否有改變Redis中的資料的事件。例如,有一個客戶端刪除了Redis中鍵為 mykey的資料,該操作會觸發兩條訊息,mykey del和del mykey,前者屬於頻道keysapce,表示keyspace發生的變化,後者屬於頻道keyevent,表示執行的操作。 
這裡寫圖片描述

2.5 Redis釋出訂閱與ActiveMQ的比較

(1)ActiveMQ支援多種訊息協議,包括AMQP,MQTT,Stomp等,並且支援JMS規範,但Redis沒有提供對這些協議的支援; 
(2)ActiveMQ提供持久化功能,但Redis無法對訊息持久化儲存,一旦訊息被髮送,如果沒有訂閱者接收,那麼訊息就會丟失; 
(3)ActiveMQ提供了訊息傳輸保障,當客戶端連線超時或事務回滾等情況發生時,訊息會被重新發送給客戶端,Redis沒有提供訊息傳輸保障。 
總 之,ActiveMQ所提供的功能遠比Redis釋出訂閱要複雜,畢竟Redis不是專門做釋出訂閱的,但是如果系統中已經有了Redis,並且需要基本 的釋出訂閱功能,就沒有必要再安裝ActiveMQ了,因為可能ActiveMQ提供的功能大部分都用不到,而Redis的釋出訂閱機制就能滿足需求。