1. 程式人生 > >Redis釋出與訂閱模式

Redis釋出與訂閱模式

Redis的Pub/Sub實現了釋出/訂閱訊息正規化,釋出者將訊息釋出到不同的頻道,訂閱者訂閱感興趣的頻道訊息,而不需要關心是誰在釋出。這種釋出者和訂閱者的解耦合方式可以極大的擴充套件的擴充套件性網路拓撲。
為了訂閱foo和bar,客戶端發出一個訂閱的頻道名稱:

SUBSCRIBE foo bar

其他客戶端發到這個頻道的訊息將會被推送到所有訂閱該頻道的客戶端。
客戶端訂閱一個或多個頻道而不必發出命令,儘管他能訂閱和取消訂閱其他頻道。訂閱和取消訂閱的響應被封裝在傳送的訊息中,以便客戶端只需要讀一個連續的訊息流,其中第一個元素表示訊息型別。

推送訊息的格式

訊息格式包括三個元素 。
第一個元素是訊息型別:

  • subscribe: 表示我們成功訂閱到響應的第二個元素提供的頻道。第三個引數代表我們現在訂閱的頻道的數量。
  • unsubscribe:表示我們成功取消訂閱到響應的第二個元素提供的頻道。第三個引數代表我們目前訂閱的頻道的數量。當最後一個引數是0的時候,我們不再訂閱到任何頻道。當我們在Pub/Sub以外狀態,客戶端可以發出任何redis命令。
  • message: 這是另外一個客戶端發出的釋出命令的結果。第二個元素是來源頻道的名稱,第三個引數是實際訊息的內容。

資料庫與作用域

釋出/訂閱與key所在空間沒有關係,它不會受任何級別的干擾,包括不同資料庫編碼。 釋出在db 10,訂閱可以在db 1。 如果你需要區分某些頻道,可以通過在頻道名稱前面加上所在環境的名稱(例如:測試環境,演示環境,線上環境等)。

協議示例

SUBSCRIBE first second
*3
$9
subscribe
$5
first
:1
*3
$9
subscribe
$6
second
:2

此時,從另一個客戶端我們發出關於頻道名稱為second的操作:

> PUBLISH second Hello

這是第一個客戶端收到的:

*3
$7
message
$6
second
$5
Hello

現在客戶端用沒有任何引數的 UNSUBSCRIBE命令取消訂閱所有頻道:

UNSUBSCRIBE
*3
$11
unsubscribe
$6
second
:1
*3
$11
unsubscribe
$5
first :0

模式匹配訂閱

Redis 的Pub/Sub實現支援模式匹配。客戶端可以訂閱全風格的模式以便接收所有來自能匹配到給定模式的頻道的訊息。
比如:

PSUBSCRIBE news.*

將接收所有發到news.art.figurative, news.music.jazz等等的訊息,所有模式都是有效的,所以支援多萬用字元。

PUNSUBSCRIBE news.*

將取消訂閱匹配該模式的客戶端,這個呼叫不影響其他訂閱。
當作模式匹配結果的訊息會以不同的格式傳送:
訊息型別是pmessage:這是另一客戶端發出的PUBLISH命令的結果,匹配一個模式匹配訂閱。第一個元素是原匹配的模式,第三個元素是原頻道名稱,最後一個元素是實際訊息內容。
同樣的,系統預設 SUBSCRIBE 和 UNSUBSCRIBE, PSUBSCRIBE 和 PUNSUBSCRIBE 命令在傳送 psubscribe 和punsubscribe型別的訊息時使用像subscribe 和 unsubscribe一樣的訊息格式。

同時匹配模式和頻道訂閱的訊息

客戶端可能多次接收一個訊息,如果它訂閱的多個模式匹配了同一個釋出的訊息,或者它訂閱的模式和頻道同時匹配到一個訊息。就像下面的例子:

SUBSCRIBE foo
PSUBSCRIBE f*

上面的例子中,如果一個訊息被髮送到foo,客戶端會接收到兩條訊息:一條message型別,一條pmessage型別。

模式匹配統計的意義

在 subscribe, unsubscribe, psubscribe 和 punsubscribe 訊息型別中,最後一個引數是依然活躍的訂閱數。 這個數字是客戶端依然訂閱的頻道和模式的總數。只有當退訂頻道和模式的數量下降到0時客戶端才會退出Pub/Sub狀態。