想要看更加舒服的排版、更加準時的推送
關注公衆號“不太靈光的程序員”
每日八點有乾貨推送
轉載自公衆號“不太靈光的程序員” 《基於Redis實現消息隊列的6種方案之方案簡述(中)》
閱讀原文
在《基於Redis實現消息隊列的6種方案之方案簡述(上)》中我們講到了基於List類型實現的消息隊列,今天我們來講下優先隊列的實現。
Redis有序集合的特點
回憶下優先隊列的特點,能保證每次取出的元素都是隊列中優先級別最高的。這一特點是使用List類型無法滿足的,數據只能是先進先出的,那我們來看下Sorted Set類型的特點。
有序集合(Sorted Set)是不允許重複的String類型元素的集合,且每個元素都會關聯一個Double類型的分數。
有序集合的成員是唯一的,但分數是可以重複。集合中最大的成員數爲 232 - 1 等於4294967295, 也就是每個集合可存儲40多億個成員。
基於Sorted Set以上的特點在實際開發中有許多的應用,比如做遊戲的實時戰績排行榜、博客中文章點贊排行榜等各類排行榜和優先隊列的實現。
基於Sorted Set的實現方案
- ZADD在集合中添加一個帶有分數的元素。
- ZRANGE返回有序集中,指定區間內的成員,其中成員的位置按分數值遞增(從小到大)來排序;我們使用0,0區間來獲取處於頂部的元素。
ZREVRANGE與ZRANGE不同的是成員的位置按分數值遞減(從大到小)來排列。 - ZREM用來移除有序集中的一個元素,不存在的成員將被忽略。當消費0,0區間元素成功後,移除該元素。
優點:
- Sorted Set類型是基於使用了hash和skiplist兩種設計實現;添加和刪除都需要修改skiplist,所以複雜度爲O(log(n));查找元素的話可以直接使用hash,其複雜度爲O(1)
- 可以實現按權值取元素
- Redis支持消息持久化,在服務端數據是安全的
缺點:
- 消費確認機制需要單獨實現,我覺得還是需要一個正在消費隊列來實現,這樣還可以使用多個客戶端來同時處理隊列消息了
- 不支持阻塞式獲取
- 不允許重複消息
- 不支持分組消費
- Sorted Set不僅可以實現優先隊列,還可以將權值當做有序隊列的自定義序號,例如使用時間戳就可以實現一個有序隊列了,但是如果是做有序隊列當然沒有List類型來的方便了。
基於PUB/SUB,訂閱/發佈模式的實現方案
- SUBSCRIBE用於訂閱一個給定模式信道
- PUBLISH用於將消息發送到指定的信道
- UNSUBSCRIBE用於取消訂閱指定信道
生產者和消費者通過相同的一個信道進行交互。信道其實也就是隊列。通常會有多個消費者。多個消費者訂閱同一個信道,當生產者向信道發佈消息時,該信道會立即將消息逐一發布給每個消費者。所以該信道對於消費者是發散的信道,每個消費者都可以得到相同的消息。典型的一對多的關係。
優點:
- 典型的廣播模式,一個消息可以發佈到多個消費者
- 多信道訂閱,消費者可以同時訂閱多個信道,從而接收多類消息
- 消息即時發送,消息不用等待消費者讀取,消費者會自動接收到信道發佈的消息
缺點:
- 消息一旦發佈,不能接收。換句話就是發佈時若客戶端不在線,則消息丟失,不能尋回
- 不能保證每個消費者接收的時間是一致的
- 若消費者客戶端出現消息積壓,到一定程度,會被強制斷開,導致消息意外丟失。通常發生在消息的生產遠大於消費速度時
可見,Pub/Sub 模式不適合做消息存儲,消息積壓類的業務,而是擅長處理廣播,即時通訊,即時反饋的業務。
懂了啵!!!
會在《基於Redis實現消息隊列的6種方案之方案簡述(下)》主要介紹使用Stream類型實現的消息隊列的方案。
感覺用就點個關注、點個看一看噢