Redis消息隊列


1.生產消費者模型

消息對列

在生活中,其實有很多的例子,都類似消息隊列。

比如:工廠生產出來的面包,交給超市,商場來出售,客戶通過超市,商場來買面包,客戶不會針對某一個工廠去選擇,只管從超市買出來,工廠也不會管是哪一個客戶買了面包,只管生產出來之后,交給超市,商場來處理。

消息隊列(Message Queue)是一種應用間的通信方式,消息發送后可以立即返回,有消息系統來確保信息的可靠專遞,消息生產者只管把消息發布到MQ中而不管誰來取,消息消費者只管從MQ中取消息而不管誰發布的,這樣發布者和使用者都不用知道對方的存在。

使用消息隊列

首先,我們可以知道,消息隊列是一種異步的工作機制,比如說日志收集系統,為了避免數據在傳輸過程中丟失,還有訂單系統,下單后,會生成對應的單據,庫存的扣減,消費信息的發送,一個下單,產生這么多的消息,都是通過一個操作的觸發,然后將其他的消息放入消息隊列中,依次產生。再就是很多網站的,秒殺活動之類的,前多少名用戶會便宜,都是通過消息隊列來實現的。

這些例子,都是通過消息隊列,來實現,業務的解耦,最終數據的一致性,廣播,錯峰流控等等,從而完成業務的邏輯。

消息隊列產品

1)rabbit-MQ(最初起源於金融系統,用於分布式系統中存儲轉發消息。OpenStack)
2)Zero-MQ(SaltStack)
3)Kafka(JAVA)
4)redis(key:value數據庫,緩存,消息隊列)

 2.Redis發布消息的兩種模式

任務隊列:顧名思義,就是“傳遞消息的隊列”。與任務隊列進行交互的實體有兩類,一類是生產者(producer),另一類則是消費者(consumer)。生產者將需要處理的任務放入任務隊列中,而消費者則不斷地從任務獨立中讀入任務信息並執行。

任務隊列的好處
1)松耦合。
生產者和消費者只需按照約定的任務描述格式,進行編寫代碼。
2)易於擴展。
多消費者模式下,消費者可以分布在多個不同的服務器中,由此降低單台服務器的負載。

發布-訂閱模式(publish-subscribe)

其實從Pub/Sub的機制來看,它更像是一個廣播系統,多個訂閱者(Subscriber)可以訂閱多個頻道(Channel),多個發布者(Publisher)可以往多個頻道(Channel)中發布消息

可以這么簡單的理解:
1)Subscriber:收音機,可以收到多個頻道,並以隊列方式顯示
2)Publisher:電台,可以往不同的FM頻道中發消息
3)Channel:不同頻率的FM頻道

一個發布者多個訂閱者模型

主要應用:通知、公告

多個發布者一個訂閱者模型

可以將PubSub做成獨立的HTTP接口,各應用程序作為Publisher向Channel中發送消息,Subscriber端收到消息后執行相應的業務邏輯,比如寫數據庫,顯示等等。
主要應用:排行榜、投票、計數。

多個發布者多個訂閱者模型

故名思議,就是可以向不同的Channel中發送消息,由不同的Subscriber接收。
主要應用:群聊、聊天。

 

Redis發布訂閱實踐

1)PUBLISH channel msg
將信息 message 發送到指定的頻道 channel

2)SUBSCRIBE channel [channel ...]
訂閱頻道,可以同時訂閱多個頻道

3)UNSUBSCRIBE [channel ...]
取消訂閱指定的頻道, 如果不指定頻道,則會取消訂閱所有頻道

4)PSUBSCRIBE pattern [pattern ...]
訂閱一個或多個符合給定模式的頻道,每個模式以 * 作為匹配符,比如 it* 匹配所  有以 it 開頭的頻道( it.news 、 it.blog 、 it.tweets 等等), news.* 匹配所有  以 news. 開頭的頻道( news.it 、 news.global.today 等等),諸如此類

5)PUNSUBSCRIBE [pattern [pattern ...]]
退訂指定的規則, 如果沒有參數則會退訂所有規則

6)PUBSUB subcommand [argument [argument ...]]
查看訂閱與發布系統狀態

_注意:_使用發布訂閱模式實現的消息隊列,當有客戶端訂閱channel后只能收到后續發布到該頻道的消息,之前發送的不會緩存,必須Provider和Consumer同時在線。

訂閱單個頻道

#第一個窗口
#登錄Redis
[root@db01 ~]# redis-cli -a 123
#在訂閱者的服務器上輸入訂閱zls
127.0.0.1:6379> SUBSCRIBE zls
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "zls"
3) (integer) 1

#第二個窗口
#登錄Redis
[root@db01 ~]# redis-cli -a 123
#在發布者的服務器上輸入信息
127.0.0.1:6379> PUBLISH zls "The Nice Boy Like Me."
(integer) 1

#第一個窗口
#在訂閱者的服務器上會看到如下信息
1) "message"
2) "zls"
3) "The Nice Boy Like Me."

訂閱多個頻道

#第一個窗口
#登錄Redis
[root@db01 ~]# redis-cli -a 123
#在訂閱者服務器上輸入訂閱所有頻道
127.0.0.1:6379> PSUBSCRIBE *
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "*"
3) (integer) 1

#第二個窗口
#在發布者服務器上輸入多頻道信息
127.0.0.1:6379> PUBLISH zls "The Nice Boy Like Me."
(integer) 1
127.0.0.1:6379> PUBLISH bgx "The Ugly Old Man Like Me."
(integer) 1

#第一個窗口
#在訂閱者的服務器上會看到如下信息
1) "pmessage"
2) "*"
3) "zls"
4) "The Nice Boy Like Me."


1) "pmessage"
2) "*"
3) "bgx"
4) "The Ugly Old Man Like Me."

消息隊列系統對比

客戶端在執行訂閱命令之后進入了訂閱狀態,只能接收 SUBSCRIBE 、PSUBSCRIBE、 UNSUBSCRIBE 、PUNSUBSCRIBE 四個命令。 開啟的訂閱客戶端,無法收到該頻道之前的消息,因為 Redis 不會對發布的消息進行持久化。 和很多專業的消息隊列系統(例如Kafka、RocketMQ、RabbitMQ)相比,Redis的發布訂閱略顯粗糙。

例如:無法實現消息堆積和回溯。但勝在足夠簡單,如果當前場景可以容忍的這些缺點,也不失為一個不錯的選擇。

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM