【你不瞭解的Redis】基於Redis實現消息隊列的6種方案之方案簡述(上)基於List的LPUSH+/RPOP/BRPOP/BRPOPLPUSH的實現

想要看更加舒服的排版、更加準時的推送
關注公衆號“不太靈光的程序員”
每日八點有乾貨推送
轉載自公衆號“不太靈光的程序員” 《基於Redis實現消息隊列的6種方案之方案簡述(上)》
閱讀原文

大家好,這次我會帶大家根據實際的業務場景來學習下基於Redis是如何實現消息隊列的,因爲大多數關注我的朋友都是初學者,我會從比較基礎的知識點講起。

有那麼多的消息隊列產品爲什麼要用Redis去實現呢??

不光市面上的消息隊列產品多,而且很多東西都是可以拿來做消息隊列服務的,可以存儲的都可以做隊列的,比如文件、數據庫、管道啊都是可以做隊列的。

Redis做消息隊列就因爲簡單封裝下LPUSH和RPOP就可以支撐百萬日活的服務;緩存服務大家都需要用的,開發也不用再次學習;部署一套也就搞定了。

Redis支持集羣部署的,讀寫性能滿足不了,加機器!容易宕機穩定性不了,加機器!!上萬臺服務器纔會產生的集羣瓶頸也不是一般公司能達到的集羣規模。

Redis還是單線程的,就根本不會有競爭的情況出現,都這麼簡單了爲啥不用呢。

Redis本來都不做消息隊列的,最後被自己打敗了,在Redis5.0中增加了Stream類型對消息隊列進行完善的實現。

1 基於Redis實現消息隊列的6種方案

  • 基於List的 LPUSH+RPOP 的實現
  • 基於List的 LPUSH+BRPOP 的實現
  • 基於List的 LPUSH+LRANGE+RPOP 的實現
  • 基於List的 LPUSH+BRPOPLPUSH+LREM 的實現
  • 基於Sorted Set 的實現
  • PUB/SUB,訂閱/發佈模式
  • 基於Stream類型的實現

一、基於List的 LPUSH+RPOP 的實現方案

  • LPUSH在頭部(List的左邊)添加一個新的元素並返回List長度,充當消息隊列中的生成者。
  • RPOP在尾部(List的右邊)刪除一個元素並返回該元素的值,充當消息隊列中的消費者。
  • 基於List類型的插入刪除元素操作實現,就是一個典型的先進先出隊列的解決方案。

優點:

  • List類型是基於鏈表實現,插入刪除元素時間複雜度僅爲常量級,有先進先出的特點來保證數據的順序
  • Redis支持消息持久化,在服務端數據是安全的

缺點:

  • 消費確認機制實現麻煩加之不能重複消費,一但消費數據就會刪除,導致客戶端數據是不安全的,當客戶端宕機、網絡斷開會出現數據丟失,也不能實現廣播模式
  • 沒有數據權重的概念,只能先進先出
  • 當隊列中沒有元素時,消費者需要輪詢獲取數據,會增加Redis的訪問壓力,增加客戶端的cpu佔用
  • 不支持分組消費

二、基於List的 LPUSH+BRPOP 的實現方案

方案二是在方案一上針對隊列沒有元素時造成服務器資源浪費進行的優化方案,使用了BRPOP做消費者,BRPOP是阻塞的。

消費者可以設置數據不存在時的阻塞時間,來減少不必要的輪詢。

三、基於List的 LPUSH+LRANGE+RPOP 的實現

方案三是在方案一上針對客戶端數據安全進行的優化方案,使用LRANGE首先對隊列元素只做讀取不做消費,在客戶端消費完成後,再使用RPOP對服務端進行消費。

由於LRANGE不是阻塞的就又回到了方案二解決的資源浪費問題上了,無法減少不必要的輪詢。

還存在重複執行的問題,由於先讀再消費,在消費者宕機重啓後會再次讀到沒有確認消費的但是已經在消費者處理過的元素,就有了重複消費的風險。真的是繞啊。

四、基於List的 LPUSH+BRPOPLPUSH+LREM 的實現

方案四是也對客戶端數據安全進行的優化方案,是一種安全的隊列,雖然也會存在重複消費的風險,但是元素隊列的操作都是在服務端進行的,問題發生的概率會大大降低。

首先消息隊列數量增加了,一個存儲待消費消息的隊列暫且稱爲A,一個存儲正在消費消息的隊列暫且稱爲B,關鍵在與BRPOPLPUSH操作,
RPOPLPUSH是將A中隊尾的消息刪除(消費掉)並添加到B隊列的隊頭。
BRPOPLPUSH是原子性的操作,所以不用擔心從A中消費後數據丟失的問題。

BRPOPLPUSH是阻塞的,不過你也可以使用RPOPLPUSH非阻塞模式。
這個方案當然也不是完美的,還是存在客戶端宕機的情況,正在處理中的隊列存在長期不消費的消息怎麼辦?

可以再添加一臺客戶端來監控長期不消費的消息,重新將消息打回待消費的隊列,這個可以使用循環隊列的模式來實現。

懂了啵!!!

內容太多了,將會寫成系列文章

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

推薦閱讀:

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