Redis发布与订阅(pub/sub)
Redis發(fā)布與訂閱(pub/sub)
本文檔翻譯自:?http://redis.io/topics/pubsub?。
SUBSCRIBE?、?UNSUBSCRIBE?和?PUBLISH?三個(gè)命令實(shí)現(xiàn)了發(fā)布與訂閱信息泛型(Publish/Subscribe messaging paradigm), 在這個(gè)實(shí)現(xiàn)中, 發(fā)送者(發(fā)送信息的客戶(hù)端)不是將信息直接發(fā)送給特定的接收者(接收信息的客戶(hù)端), 而是將信息發(fā)送給頻道(channel), 然后由頻道將信息轉(zhuǎn)發(fā)給所有對(duì)這個(gè)頻道感興趣的訂閱者。
發(fā)送者無(wú)須知道任何關(guān)于訂閱者的信息, 而訂閱者也無(wú)須知道是那個(gè)客戶(hù)端給它發(fā)送信息, 它只要關(guān)注自己感興趣的頻道即可。
對(duì)發(fā)布者和訂閱者進(jìn)行解構(gòu)(decoupling), 可以極大地提高系統(tǒng)的擴(kuò)展性(scalability), 并得到一個(gè)更動(dòng)態(tài)的網(wǎng)絡(luò)拓?fù)?#xff08;network topology)。
比如說(shuō), 要訂閱頻道?foo?和?bar?, 客戶(hù)端可以使用頻道名字作為參數(shù)來(lái)調(diào)用?SUBSCRIBE?命令:
redis> SUBSCRIBE foo bar當(dāng)有客戶(hù)端發(fā)送信息到這些頻道時(shí), Redis 會(huì)將傳入的信息推送到所有訂閱這些頻道的客戶(hù)端里面。
正在訂閱頻道的客戶(hù)端不應(yīng)該發(fā)送除?SUBSCRIBE?和?UNSUBSCRIBE?之外的其他命令。 其中,?SUBSCRIBE?可以用于訂閱更多頻道, 而?UNSUBSCRIBE?則可以用于退訂已訂閱的一個(gè)或多個(gè)頻道。
SUBSCRIBE?和?UNSUBSCRIBE?的執(zhí)行結(jié)果會(huì)以信息的形式返回, 客戶(hù)端可以通過(guò)分析所接收信息的第一個(gè)元素, 從而判斷所收到的內(nèi)容是一條真正的信息, 還是?SUBSCRIBE?或?UNSUBSCRIBE?命令的操作結(jié)果。
信息的格式
頻道轉(zhuǎn)發(fā)的每條信息都是一條帶有三個(gè)元素的多條批量回復(fù)(multi-bulk reply)。
信息的第一個(gè)元素標(biāo)識(shí)了信息的類(lèi)型:
- subscribe?: 表示當(dāng)前客戶(hù)端成功地訂閱了信息第二個(gè)元素所指示的頻道。 而信息的第三個(gè)元素則記錄了目前客戶(hù)端已訂閱頻道的總數(shù)。
- unsubscribe?: 表示當(dāng)前客戶(hù)端成功地退訂了信息第二個(gè)元素所指示的頻道。 信息的第三個(gè)元素記錄了客戶(hù)端目前仍在訂閱的頻道數(shù)量。 當(dāng)客戶(hù)端訂閱的頻道數(shù)量降為?0?時(shí), 客戶(hù)端不再訂閱任何頻道, 它可以像往常一樣, 執(zhí)行任何 Redis 命令。
- message?: 表示這條信息是由某個(gè)客戶(hù)端執(zhí)行?PUBLISH?命令所發(fā)送的, 真正的信息。 信息的第二個(gè)元素是信息來(lái)源的頻道, 而第三個(gè)元素則是信息的內(nèi)容。
舉個(gè)例子, 如果客戶(hù)端執(zhí)行以下命令:
redis> SUBSCRIBE first second那么它將收到以下回復(fù):
1) "subscribe" 2) "first" 3) (integer) 11) "subscribe" 2) "second" 3) (integer) 2如果在這時(shí), 另一個(gè)客戶(hù)端執(zhí)行以下?PUBLISH?命令:
redis> PUBLISH second Hello那么之前訂閱了?second?頻道的客戶(hù)端將收到以下信息:
1) "message" 2) "second" 3) "hello"當(dāng)訂閱者決定退訂所有頻道時(shí), 它可以執(zhí)行一個(gè)無(wú)參數(shù)的?UNSUBSCRIBE?命令:
redis> UNSUBSCRIBE這個(gè)命令將接到以下回復(fù):
1) "unsubscribe" 2) "second" 3) (integer) 11) "unsubscribe" 2) "first" 3) (integer) 0訂閱模式
Redis 的發(fā)布與訂閱實(shí)現(xiàn)支持模式匹配(pattern matching): 客戶(hù)端可以訂閱一個(gè)帶?*?號(hào)的模式, 如果某個(gè)/某些頻道的名字和這個(gè)模式匹配, 那么當(dāng)有信息發(fā)送給這個(gè)/這些頻道的時(shí)候, 客戶(hù)端也會(huì)收到這個(gè)/這些頻道的信息。
比如說(shuō),執(zhí)行命令
redis> PSUBSCRIBE news.*的客戶(hù)端將收到來(lái)自?news.art.figurative?、?news.music.jazz?等頻道的信息。
客戶(hù)端訂閱的模式里面可以包含多個(gè) glob 風(fēng)格的通配符, 比如?*?、???和?[...]?, 等等。
執(zhí)行命令
redis> PUNSUBSCRIBE news.*將退訂?news.*?模式, 其他已訂閱的模式不會(huì)被影響。
通過(guò)訂閱模式接收到的信息, 和通過(guò)訂閱頻道接收到的信息, 這兩者的格式不太一樣:
- 通過(guò)訂閱模式而接收到的信息的類(lèi)型為?pmessage?: 這代表有某個(gè)客戶(hù)端通過(guò)?PUBLISH?向某個(gè)頻道發(fā)送了信息, 而這個(gè)頻道剛好匹配了當(dāng)前客戶(hù)端所訂閱的某個(gè)模式。 信息的第二個(gè)元素記錄了被匹配的模式, 第三個(gè)元素記錄了被匹配的頻道的名字, 最后一個(gè)元素則記錄了信息的實(shí)際內(nèi)容。
客戶(hù)端處理?PSUBSCRIBE?和?PUNSUBSCRIBE?返回值的方式, 和客戶(hù)端處理?SUBSCRIBE?和?UNSUBSCRIBE?的方式類(lèi)似: 通過(guò)對(duì)信息的第一個(gè)元素進(jìn)行分析, 客戶(hù)端可以判斷接收到的信息是一個(gè)真正的信息, 還是?PSUBSCRIBE?或?PUNSUBSCRIBE?命令的返回值。
通過(guò)頻道和模式接收同一條信息
如果客戶(hù)端訂閱的多個(gè)模式匹配了同一個(gè)頻道, 或者客戶(hù)端同時(shí)訂閱了某個(gè)頻道、以及匹配這個(gè)頻道的某個(gè)模式, 那么它可能會(huì)多次接收到同一條信息。
舉個(gè)例子, 如果客戶(hù)端執(zhí)行了以下命令:
SUBSCRIBE foo PSUBSCRIBE f*那么當(dāng)有信息發(fā)送到頻道?foo?時(shí), 客戶(hù)端將收到兩條信息: 一條來(lái)自頻道?foo?,信息類(lèi)型為?message?; 另一條來(lái)自模式?f*?,信息類(lèi)型為?pmessage?。
訂閱總數(shù)
在執(zhí)行?SUBSCRIBE?、?UNSUBSCRIBE?、?PSUBSCRIBE?和?PUNSUBSCRIBE?命令時(shí), 返回結(jié)果的最后一個(gè)元素是客戶(hù)端目前仍在訂閱的頻道和模式總數(shù)。
當(dāng)客戶(hù)端退訂所有頻道和模式, 也即是這個(gè)總數(shù)值下降為?0?的時(shí)候, 客戶(hù)端將退出訂閱與發(fā)布狀態(tài)。
編程示例
Pieter Noordhuis 提供了一個(gè)使用 EventMachine 和 Redis 編寫(xiě)的?高性能多用戶(hù)網(wǎng)頁(yè)聊天軟件?, 這個(gè)軟件很好地展示了發(fā)布與訂閱功能的用法。
客戶(hù)端庫(kù)實(shí)現(xiàn)提示
因?yàn)樗薪邮盏降男畔⒍紩?huì)包含一個(gè)信息來(lái)源:
- 當(dāng)信息來(lái)自頻道時(shí),來(lái)源是某個(gè)頻道;
- 當(dāng)信息來(lái)自模式時(shí),來(lái)源是某個(gè)模式。
因此, 客戶(hù)端可以用一個(gè)哈希表, 將特定來(lái)源和處理該來(lái)源的回調(diào)函數(shù)關(guān)聯(lián)起來(lái)。 當(dāng)有新信息到達(dá)時(shí), 程序就可以根據(jù)信息的來(lái)源, 在 O(1) 復(fù)雜度內(nèi), 將信息交給正確的回調(diào)函數(shù)來(lái)處理。
from:?http://redisdoc.com/topic/pubsub.html
總結(jié)
以上是生活随笔為你收集整理的Redis发布与订阅(pub/sub)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Redis通信协议(protocol)
- 下一篇: Redis复制(Replication)