redis訂閱與發佈系統

1、概述
一、redis經過publish、subscribe等命令實現了訂閱與發佈模式。
二、這個功能提供兩種信息機制,分別是訂閱/發佈到頻道和訂閱/發佈到模式。redis

2、頻道的訂閱與信息發送
一、redis的subscribe命令可讓客戶端訂閱任意數量的頻道,每當有新信息發送到被訂閱的頻道時,信息就會被髮送給全部訂閱指定頻道的客戶端。
二、做爲例子,下圖展現了頻道channel1,以及訂閱這個頻道的三個客戶端------client二、client5和client1之間的關係:
服務器

三、當有新消息經過publish命令發送給頻道channel1時,這個消息就會被髮送給訂閱它的三個客戶端:
spa

四、每一個redis服務器進程都維持着一個表示服務器狀態的redis.h/redisServer結構,結構的pubsub_channels屬性是一個字典,這個字典就用於保存訂閱頻道的信息;
五、其中,字典的鍵爲正在被訂閱的頻道,而字典的值則是一個鏈表,鏈表中保存了全部訂閱這個頻道的客戶端3d

六、好比說,在下圖展現的這個pubsub_channels示例中,client二、client5和client1就訂閱了channel1,而其餘頻道也分別被別的客戶端所訂閱:
blog

七、當客戶端調用subscribe命令時,程序就將客戶端和要訂閱的頻道在pubsub_channels字典中關聯起來;
八、舉個例子,若是客戶端client10086執行命令subscribe channel1 channel2 channel3,那麼前面只是的pubsub_channels將變成下面這個樣子
進程

八、經過pubsub_channels字典,程序只要檢查某個頻道是否爲字典的鍵,就能夠知道該頻道是否正在被客戶端訂閱;只要去除某個鍵的值,就能夠獲得全部訂閱該頻道的客戶端的信息。ip

九、瞭解了pubsub_channels字典的結構以後,解釋publish命令的實現就很是簡單了:當調用publish channel message命令,程序首先根據channel定位到字典的鍵,而後將信息發送給字典值鏈表中的全部客戶端。it

十、使用unsubscribe命令能夠推定指定的頻道,這個命令執行的是訂閱的反操做:他從pubsub_channels字典的給定頻道(鍵)中,刪除關於當前客戶端的信息,這樣被退訂頻道的信息就不會再發送給這個客戶端。ast


3、模式的訂閱與信息發送
(一)訂閱模式
一、當使用publish命令發送信息到某個頻道時,不只全部訂閱該頻道的客戶端會受到信息,若是有某個/某些模式和這個頻道匹配的話,那麼全部訂閱這個/這些頻道的客戶端也一樣會收到信息。cli

二、下圖展現了一個帶有頻道和模式的例子,其中tweet.shop.*模式匹配了tweet.shop.kindle頻道和tweet.shop.ipad頻道,而且有不一樣的客戶端分別訂閱他們三個:

三、當有信息發送到tweet.shop.kindle頻道時,信息除了發送給clientX和clientY以外,還會發送給訂閱tweet.shop.*模式的client123和client256

四、redisServer.pubsub_patterns屬性是一個鏈表,鏈表中保存着全部和模式相關的信息:
  struct redisServer{
    //...
    list *pubsub_patterns;
    //...
  }
鏈表中的每一個節點都包含一個reids.h/pubsubPattern結構:
  typedef struct pubsubPattern{
    redisClient *client;//哪個客戶端
    robj *pattern;//訂閱的那個模式
  }pubsubPattern;

client屬性保存着訂閱模式的客戶端,而pattern屬性則保存着被訂閱的模式。
每當調用PSUBSCRIBE命令訂閱一個模式時,程序就建立一個包含客戶端信息和被訂閱模式的pubsubPattern結構,並將該結構添加到redisServer.pubsub_patterns鏈表中。

下圖展現了一個包含兩個模式的pubsub_patterns鏈表,其中client123和client256都正在訂閱tweet.shop.*模式:

若是這時客戶端client10086執行PSUBSCRIBE broadcast.list.*,那麼pubsub_patterns鏈表將被更新成這樣:

(二)發送信息到模式
PUBLISH除了將message發送到全部訂閱channel的客戶端以外,它還會降channel和pubsub_patterns中的模式進行對比,若是channel和某個模式匹配的話,那麼也將message發送到訂閱那個模式的客戶端。

舉個例子,若是redis服務器的pubsub_patterns狀態以下:


那麼當某個客戶端發送信息"Amazon Kindle,$69."到tweet.shop.kindle頻道時,除了全部訂閱了tweet.shop.kindle頻道的客戶端會受到信息以外,客戶端client123和client256頁一樣會收到信息,由於這兩個客戶端訂閱的tweet.shop.*模式和tweet.shop.kindle頻道匹配。

(三)退訂模式
使用PUNSUBSCRIBE命令能夠退訂指定的模式,這個命令執行的是訂閱模式的反操做:程序會刪除redisServer.pubsub_patterns鏈表中,全部和被退訂模式相關聯的pubsubPattern結構,這樣客戶端就不會再收到和模式相匹配的頻道發來的信息。


4、redis訂閱與發佈系統的基本命令

  • 命令名稱:subscribe
  • 語法:subscribe channel [channel ...]
  • 功能:
    • 訂閱給定的一個或多個頻道的信息。
  • 返回值:
    • 接收到的信息。

 

  • 命令名稱:psubscribe
  • 語法:psubscribe pattern [pattern ...]
  • 功能:
    • 訂閱一個或多個符合給定模式的頻道。
    • 每一個模式以*做爲匹配符,好比it*匹配全部以it開頭的頻道(it.news、it.blog、it.tweets等)
  • 返回值:
    • 接收到的信息。

 

  • 命令名稱:publish
  • 語法:publish channel message
  • 功能:1)將信息message發送到指定的頻道channel
  • 返回值:1)接收到信息message的訂閱者數量。

 

  • 命令名稱:unsubscribe
  • 語法:unsubscribe [channel[channel...]]
  • 功能:
    • 指示客戶端退訂全部給定頻道。
    • 若是沒有頻道被指定,也便是,一個無參數的unsubscribe調用被執行,那麼客戶端使用subscribe命令訂閱的全部頻道都會被退訂。在這種狀況下,命令會返回一個信息,告知客戶端全部被退訂的頻道。
  • 返回值:
    • 退訂結果。

 

  • 命令名稱:punsubscribe
  • 語法:punsubscribe [channel[channel...]]
  • 功能:
    • 指示客戶端退訂全部給定模式。
    • 若是沒有模式被指定,也便是,一個無參數的punsubscribe調用被執行,那麼客戶端使用subscribe命令訂閱的全部模式都會被退訂。在這種狀況下,命令會返回一個信息,告知客戶端全部被退訂的模式。
  • 返回值:
    • 退訂結果。

 

  • 命令名稱:pubsub
  • 語法:pubsub <subcommand> [argument [argument...]]
  • 功能:
    • pubsub是一個查看訂閱與發佈系統裝填的內省命令,它由數個不一樣格式的子命令組成。
  • 子命令:
    • pubsub channels [pattern]
      • 列出當前的活躍頻道。
      • 活躍頻道指的是那些至少有一個訂閱者的頻道,訂閱模式的客戶端不計算在內。
      • 若是不給出pattern參數,那麼列出訂閱與發佈系統中的全部活躍頻道。
      • 若是給出pattern參數,那麼只列出和給定模式pattern相匹配的那些活躍頻道。
    • pubsub numsub [channel-1 ... channel-N]
      • 返回給定頻道的訂閱者數量,訂閱模式的客戶端不計算在內。
    • pubsub numpat
      • 返回訂閱模式的數量。
      • 注意:這個命令返回的不是訂閱模式的客戶端的數量,而是客戶端訂閱的全部模式的數量總和。
相關文章
相關標籤/搜索