1、簡(jiǎn)介

李子捌把話說(shuō)在前頭,如果你是面試或者為了了解知識(shí)來(lái)學(xué)習(xí)這一知識(shí)點(diǎn),我覺(jué)得是有必要的;但是如果你是作為公司的技術(shù)負(fù)責(zé)人或者項(xiàng)目技術(shù)選型來(lái)使用Redis的Pub/Sub做消息的發(fā)布訂閱,如果你不是走投無(wú)路了,那么你可能值得斟酌一下。Redis的Pub/Sub發(fā)布訂閱,是Redis一步步完善消息隊(duì)列功能的一個(gè)進(jìn)步點(diǎn),雖然現(xiàn)在沒(méi)人用Pub/Sub做消息隊(duì)列,但是它的思想和功能也是值得玩一下的,這個(gè)就是我寫(xiě)這篇文章的主要原因。

Redis 發(fā)布訂閱 (pub/sub) 是一種消息通信模式:發(fā)送者 (pub) 發(fā)送消息,訂閱者 (sub) 接收消息。

  • pub -> publisher
  • sub -> subscriber

Redis客戶端訂閱一個(gè)頻道非常簡(jiǎn)單,它可以訂閱任意數(shù)量的頻道。

如下圖,Redis客戶端訂閱(subscriber)頻道(channel)

#yyds干貨盤點(diǎn)#Redis之Pub/Sub_持久化


如下圖,當(dāng)消息發(fā)送到客戶端訂閱的頻道(channel)時(shí),這個(gè)消息就會(huì)被訂閱的所有未故障的客戶端接接收到

#yyds干貨盤點(diǎn)#Redis之Pub/Sub_持久化_02


2、實(shí)例演示

演示Redis的發(fā)布訂閱,我們需要開(kāi)啟多個(gè)客戶端,訂閱頻道(channel)。


2.1 普通訂閱

如下我會(huì)啟動(dòng)4個(gè)客戶端,第一個(gè)客戶端用來(lái)發(fā)布消息,其他的用來(lái)訂閱頻道,接收消息。

#yyds干貨盤點(diǎn)#Redis之Pub/Sub_客戶端_03


客戶端2、客戶端3、客戶端4同時(shí)訂閱news和weather頻道(channel)

#yyds干貨盤點(diǎn)#Redis之Pub/Sub_消息中間件_04


客戶端1向頻道news/weather發(fā)布消息

#yyds干貨盤點(diǎn)#Redis之Pub/Sub_redis_05

此時(shí)可以看到三個(gè)客戶端均接收客戶端1向頻道news/weather發(fā)布的消息

#yyds干貨盤點(diǎn)#Redis之Pub/Sub_持久化_06


2.2 模式訂閱

Redis為了方便同時(shí)訂閱多個(gè)模式的頻道,也有類似市面上常見(jiàn)的MQ中模式訂閱功能(如Rabbit MQ中的topic),這個(gè)功能可以匹配符的方式進(jìn)行訂閱。


比如我需要訂閱以fund.開(kāi)頭,任意字符結(jié)尾的頻道,就可以使用如下的訂閱方式


#yyds干貨盤點(diǎn)#Redis之Pub/Sub_客戶端_07

嘗試向fund.nuoan發(fā)布消息

#yyds干貨盤點(diǎn)#Redis之Pub/Sub_持久化_08

訂閱了fund.*的客戶端,成功接收到消息

#yyds干貨盤點(diǎn)#Redis之Pub/Sub_消息中間件_09



3、Pub/Sub為什么被拋棄

關(guān)于Redis的Pub/Sub為什么被拋棄,最主要的原因是它無(wú)法持久化,沒(méi)有實(shí)現(xiàn)持久化機(jī)制的Pub/Sub,無(wú)法做到消息的不丟失,在客戶端宕機(jī)或者Redis服務(wù)宕機(jī)的情況下,都會(huì)導(dǎo)致消息丟失。

  • 客戶端宕機(jī),客戶端無(wú)法接收消息
  • Redis服務(wù)宕機(jī),沒(méi)有客戶端能連接上,肯定也無(wú)法接收到消息


大部分情況下,我們都不會(huì)用到Redis去做消息中間件,市面上成熟且好用的消息中間件非常多,如果真的需要使用Redis來(lái)做消息中間件,可以考慮Redis 5.0的新數(shù)據(jù)結(jié)構(gòu)Stream,這個(gè)功能在Pub/Sub的基礎(chǔ)上,實(shí)現(xiàn)了持久化機(jī)制,并且大力借鑒了kafka的設(shè)計(jì)原理,完善了Redis用于實(shí)現(xiàn)消息隊(duì)列的不足之處。


關(guān)于stream的知識(shí)點(diǎn),請(qǐng)查看我的Redis專欄!