Redis pub/sub机制在实际运用场景的理解(转载)
Redis 的pub/sub機(jī)制與23種設(shè)計(jì)模式中的觀察者設(shè)計(jì)模式極為類似。但Redis對(duì)于這個(gè)機(jī)制的實(shí)現(xiàn)更為輕便和簡(jiǎn)結(jié),沒有觀察者模式的那么復(fù)雜的邏輯考慮而僅僅需要通過兩個(gè)Redis客戶端配置channel即可實(shí)現(xiàn),因此它也僅僅做了消息的"發(fā)布"和"訂閱"的實(shí)現(xiàn),而在實(shí)際處理這類場(chǎng)景時(shí)遇到的情況根本沒有考慮到。
數(shù)據(jù)可靠性無法保證
一個(gè)redis-cli發(fā)布消息n個(gè)redis-cli接受消息。消息的發(fā)布是無狀態(tài)的,即發(fā)布完消息后該redis-cli便在理會(huì)該消息是否被接受到,是否在傳輸過程中丟失,即對(duì)于發(fā)布者來說,消息是"即發(fā)即失"的.
擴(kuò)展性太差
不能通過增加消費(fèi)者來加快消耗發(fā)布者的寫入的數(shù)據(jù),如果發(fā)布者發(fā)布的消息很多,則數(shù)據(jù)阻塞在通道中已等待被消費(fèi)著來消耗。阻塞時(shí)間越久,數(shù)據(jù)丟失的風(fēng)險(xiǎn)越大(網(wǎng)絡(luò)或者服務(wù)器的一個(gè)不穩(wěn)定就會(huì)導(dǎo)致數(shù)據(jù)的丟失)
資源消耗較高
在pub/sub中消息發(fā)布者不需要獨(dú)占一個(gè)Redis的鏈接,而消費(fèi)者則需要單獨(dú)占用一個(gè)Redis的鏈接,在java中便不得獨(dú)立出分出一個(gè)線程來處理消費(fèi)者。這種場(chǎng)景一般對(duì)應(yīng)這多個(gè)消費(fèi)者,此時(shí)則有著過高的資源消耗。
對(duì)于如上的幾種不足,如果在項(xiàng)目中需要考慮的話可以使用JMS來實(shí)現(xiàn)該功能。JMS提供了消息的持久化/耐久性等各種企業(yè)級(jí)的特性。如果依然想使用Redis來實(shí)現(xiàn)并做一些數(shù)據(jù)的持久化操作,則可以根據(jù)JMS的特性來通過Redis模擬出來.
subscribe端首先向一個(gè)Set集合中增加“訂閱者ID”,此Set集合保存了“活躍訂閱”者,訂閱者ID標(biāo)記每個(gè)唯一的訂閱者,例如:sub:email,sub:web。此SET稱為“活躍訂閱者集合”
subcribe端開啟訂閱操作,并基于Redis創(chuàng)建一個(gè)以“訂閱者ID”為KEY的LIST數(shù)據(jù)結(jié)構(gòu),此LIST中存儲(chǔ)了所有的尚未消費(fèi)的消息。此LIST稱為“訂閱者消息隊(duì)列”
publish端:每發(fā)布一條消息之后,publish端都需要遍歷“活躍訂閱者集合”,并依次向每個(gè)“訂閱者消息隊(duì)列”尾部追加此次發(fā)布的消息。
到此為止,我們可以基本保證,發(fā)布的每一條消息,都會(huì)持久保存在每個(gè)“訂閱者消息隊(duì)列”中。
subscribe端,每收到一個(gè)訂閱消息,在消費(fèi)之后,必須刪除自己的“訂閱者消息隊(duì)列”頭部的一條記錄。
subscribe端啟動(dòng)時(shí),如果發(fā)現(xiàn)自己的自己的“訂閱者消息隊(duì)列”有殘存記錄,那么將會(huì)首先消費(fèi)這些記錄,然后再去訂閱。
總結(jié)
以上是生活随笔為你收集整理的Redis pub/sub机制在实际运用场景的理解(转载)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 30个有趣的Python实战项目(附源码
- 下一篇: MySQL中的alter table操作