Redis之發布 訂閱機制

2021-09-09 08:00:45 字數 3206 閱讀 7175

相關命令:

publish             發布

subscribe 訂閱

psubscribe 一種訂閱符合給定模式的所有頻道的方法

unsubscribe 退訂

punsubscribe 退訂乙個訂閱的模式

這些命令被廣泛用於構建即時通訊應用,比如網路聊天室(chatroom)和實時廣播、實時提醒等。

redis相關原始碼檔案:pubsub.c

redis> publish treehole "top secret here ..." 

(integer) 0

redis> publish chatroom "hi?"

(integer) 1

redis> subscribe chatroom 

reading messages... (press ctrl-c to quit)

1) "subscribe" # 訂閱反饋

2) "chatroom" # 訂閱的頻道

3) (integer) 1 # 目前客戶端已訂閱頻道/模式的數量

1) "message" # 資訊

2) "chatroom" # 傳送資訊的頻道

3) "hi?" # 資訊內容

subscribe 的返回值當中, 1) ""subscribe""是訂閱的反饋資訊,1)"message "的則是訂閱的頻道所傳送的資訊。

subscribe 還可以訂閱多個頻道,這樣一來它接收到的資訊就可能來自多個頻道:

redis> subscribe chatroom talk-to-jack 

reading messages... (press ctrl-c to quit)

1) "subscribe" # 訂閱 chatroom 的反饋

2) "chatroom"

3) (integer) 1

1) "subscribe" # 訂閱 talk-to-jack 的反饋

2) "talk-to-jack"

3) (integer) 2

1) "message" # 來自 chatroom 的訊息

2) "chatroom"

3) "yahoo"

1) "message" # 來自 talk-to-peter 的訊息

2) "talk-to-jack"

3) "goodmorning, peter."

redis> psubscribe it.* 

reading messages... (press ctrl-c to quit)

1) "psubscribe"

2) "it.*"

3) (integer) 1

1) "pmessage"

2) "it.*" # 匹配的模式

3) "it.news" # 訊息的**頻道

4) "redis 2.6rc5 release" # 訊息內容

1) "pmessage"

2) "it.*"

3) "it.blog"

4) "why nosql matters"

1) "pmessage"

2) "it.*"

3) "it.tweet"

4) "@redis: when will the 2.6 stable release?"

當然, psubscribe 也可以接受多個引數,從而匹配多種模式。

當乙個客戶端通過 publish 命令向訂閱者傳送資訊的時候,我們稱這個客戶端為發布者(publisher)。

而當乙個客戶端使用 subscribe 或者 psubscribe 命令接收資訊的時候,我們稱這個客戶端為訂閱者(subscriber)。

為了解耦發布者(publisher)和訂閱者(subscriber)之間的關係,redis 使用了 channel (頻道)作為兩者的中介 —— 發布者將資訊直接發布給 channel ,而 channel 負責將資訊傳送給適當的訂閱者,發布者和訂閱者之間沒有相互關係,也不知道對方的存在

redis 將所有接受和傳送資訊的任務交給 channel 來進行,而所有 channel 的資訊就儲存在 redisserver 這個結構中:

struct redisserver ;
pubsub_channels 是乙個字典,字典的鍵就是乙個個 channel ,而字典的值則是乙個鍊錶,鍊錶中儲存了所有訂閱這個 channel 的客戶端。(haspmap之類)

實現 subscribe 命令的關鍵,就是將客戶端新增到給定 channel 的訂閱鍊錶中。

函式 pubsubsubscribechannel 是 subscribe 命令的底層實現,它完成了將客戶端新增到訂閱鍊錶中的工作:

// 訂閱指定頻道 

// 訂閱成功返回 1 ,如果已經訂閱過,返回 0

int pubsubsubscribechannel(redisclient *c, robj *channel) else

// 將客戶端加入到鍊錶中

listaddnodetail(clients,c);

} /* notify the client */

addreply(c,shared.mbulkhdr[3]);

addreply(c,shared.subscribebulk);

// 返回訂閱的頻道

addreplybulk(c,channel);

// 返回客戶端當前已訂閱的頻道和模式數量的總和

addreplylonglong(c,dictsize(c->pubsub_channels)+listlength(c->pubsub_patterns));

return retval;

}

和 redisserver.pubsub_channels 屬性類似, redisserver.pubsub_patterns 屬性用於儲存所有被訂閱的模式,和 pubsub_channels 不同的是, pubsub_patterns 是乙個鍊錶(而不是字典):

struct redisserver ;

Redis發布訂閱機制

redis是乙個開源的記憶體資料庫,它以鍵值對的形式儲存資料。由於資料儲存在記憶體中,因此redis的速度很快,但是每次重啟redis服務時,其中的資料也會丟失,因此,redis也提供了持久化儲存機制,將資料以某種形式儲存在檔案中,每次重啟時,可以自動從檔案載入資料到記憶體當中。redis的架構包括...

Redis 發布訂閱機制詳解

程序間的一種訊息通訊模式 傳送者 pub 傳送訊息,訂閱者 sub 接收訊息。聯想諸多訊息中介軟體的發布訂閱模式,但是redis大多用來作為基於記憶體的分布式快取,企業中訊息中介軟體多用activemq ribbitmq等。下圖展示了頻道channel1,以及訂閱這個頻道的三個客戶端 client2...

redis之訊息訂閱發布

傳送訊息到指定的channel通道 subscribe 訂閱乙個或者多個通道 unsubscribe 取消訂閱指定的通道 psubscribe 訂閱乙個或多個符合給定模式的通道 punsubscribe 取消訂閱乙個或多個符合給定模式的通道 pubsub 檢視訂閱發布的狀態 下面通過一些簡答的示例說...