在前面的文章中或多或少有提到Redis的publish命令,它就是Redis中的發佈訂閱中的一個命令,本篇就介紹Redis中的發佈訂閱模式,以及對比使用List實現的消息隊列和傳統消息隊列Kafka的區別。
目錄
Redis6系列文章:
Redis系列(一)、CentOS7下安裝Redis6.0.3穩定版
Redis系列(六)、數據類型之有序集合ZSet(sorted_set)
Redis系列(十)、詳解Redis持久化方式AOF、RDB以及混合持久化
Redis系列(十一)、Redis6新特性之ACL安全策略(用戶權限管理)
Redis系列(十二)、Redis6集羣搭建及原理(主從、哨兵、集羣)
介紹
Redis中的訂閱、發佈實現了發佈/訂閱消息範式,發佈者不是計劃發送消息給特定的訂閱者,而是發佈消息到不同的頻道,發佈者不需要知道是哪些訂閱者訂閱了消息。訂閱者對一個或多個頻道感興趣,只需接收感興趣的消息,不需要知道是什麼樣的發佈者發佈的消息。這種發佈者和訂閱者的解耦合可以帶來更大的擴展性和更加動態的網絡拓撲。
在Redis的發佈訂閱模式中,有三個部分:
Publisher(發佈者):發送消息到頻道中,每次只能往一個頻道發送一條消息;
Subscriber(訂閱者):訂閱頻道,訂閱者可以同時訂閱多個頻道;
Channel(頻道):將發佈者發佈的消息轉發給當前訂閱此頻道的訂閱者;
使用
發佈訂閱的命令如下:
#發佈消息到指定的頻道
PUBLISH channel message
#訂閱給定的一個或多個頻道的信息
SUBSCRIBE channel [channel ...]
#訂閱一個或多個符合給定模式的頻道
PSUBSCRIBE pattern [pattern ...]
#指退訂給定的頻道
UNSUBSCRIBE [channel [channel ...]]
#退訂所有給定模式的頻道
PUNSUBSCRIBE [pattern [pattern ...]]
#查看訂閱與發佈系統狀態
PUBSUB subcommand [argument [argument ...]]
我們使用上篇文章中搭建的集羣來測試Redis的訂閱發佈模式,A節點作爲發佈者,A,B,C節點作爲訂閱者消費A節點發布的消息:
訂閱者6381:與發佈者在同一節點,訂閱www,csdn,wyk三個頻道;
訂閱者6382:訂閱符合csdn*和wyk*模式的所有頻道;
訂閱者6383:訂閱csdn頻道;
發佈者6381:分別往csdn1,csdn2,csdn,wyk四個頻道發送消息,驗證三個訂閱者接收消息的情況以及發佈者發佈消息後的返回值;
斷開後的訂閱者重新訂閱後會丟失斷開期間發佈者發佈的消息:
在集羣模式中,發佈者發佈消息後的返回值取決於訂閱者與發佈者在不在同一個節點上:
發佈者發佈消息後返回值爲與發佈者相同節點當前訂閱了該頻道的客戶端數量。
對比
在上面的示例中,大家也可以看到,Redis中的發佈訂閱非常像消息隊列,但還是有不同,我們就來對比一下Redis的List實現消息隊列以及傳統消息隊列Kafka看看有哪些不同:
對比List
與Redis中的List對比,基於List實現的消息隊列需要結合lpush + brpop來實現。
勝(多消費組):當多個客戶端同時消費同一個List消息隊列時,消費者A使用brpop消費的數據就從list中彈出了,消費者B就再也讀不到該數據,而在發佈訂閱中,多個訂閱者可以訂閱相同的頻道,頻道內的數據會分發到各個訂閱者,不會出現某一個訂閱者消費了之後,另一個訂閱者讀不到該數據的情況。
負(斷點消費):但對於List的消息隊列來說,當消費者斷開後重連,仍然可以從List中斷點消費還沒消費的數據,而發佈訂閱中,如果訂閱者斷開重連,會丟失斷開期間發佈者發佈的數據,無法恢復。
對比Kafka
Redis的發佈訂閱以及List並不是要和專業的消息隊列對標,而是可以實現類似的功能,真正在消息隊列領域做的好的有很多,RabbitMQ,ActiveMQ,RocketMQ,Kafka,Pulsar等等,發佈訂閱相比於它們有什麼異同呢?
不同點:
持久化:Kafka會將數據持久化到磁盤內,而Redis的發佈訂閱做不到;
斷點消費:上面也提到,當訂閱者斷開重連會丟失斷開期間發佈者發佈的消息,而kafka中會記錄每個消費者消費的topic的offset,因此kafka可以從斷開的offset繼續消費;
偏移量:基於上一條,同樣的kafka的消費者可以指定從某個offset開始重新消費,而Redis發佈訂閱根本不會記錄訂閱者消費的偏移量;
消費方式: 在Redis發佈訂閱中,數據消費情況是由發佈者控制的,當發佈者發佈到頻道中後,只有當前連接了頻道的訂閱者才能消費到數據,斷開重連的會失去那部分數據。而kafka中消費進度是由消費者控制的,消費者從topic中拉取數據並記錄消費的offset。
相同點:
消息模型:在JMS消息模型中有點對點和訂閱發佈兩種,Kafka和Redis發佈訂閱都是採用發佈訂閱的模型。
消費者組:Kafka裏在不同的消費者組中的消費者消費相同的topic時會各自維護一個offset,因此不會出現A消費之後的數據,B就消費不到的情況。Redis中訂閱者訂閱相同的頻道也不會出現類似的情況。
希望本文對你有幫助,請點個贊鼓勵一下作者吧~ 謝謝!