【你不瞭解的Redis】基於Redis實現消息隊列的6種方案之方案簡述(中)基於Sorted Set、PUB/SUB的實現

想要看更加舒服的排版、更加準時的推送
關注公衆號“不太靈光的程序員”
每日八點有乾貨推送
轉載自公衆號“不太靈光的程序員” 《基於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類型實現的消息隊列的方案。

感覺用就點個關注、點個看一看噢

推薦閱讀:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章