RabbitMQ 惰性佇列Lazy Queue

2021-09-07 20:53:27 字數 2327 閱讀 3145

rabbitmq 佇列分為幾種型別,按照不同維度來分,可以分為排他性佇列、普通佇列、延遲佇列、惰性佇列、發布訂閱佇列等。

今天我們討論的主角是惰性佇列 lazy queue。眾所周知,佇列可以儲存訊息並實現訊息收發,這應該是訊息佇列中最重要的功能之一。

rabbitmq提供高效服務的幾種途徑,設定ram節點、自動同步,先記憶體後磁碟的讀取方式。在佇列設定持久化後,我們讀取佇列中的訊息,如果都是先從記憶體後從磁碟讀取,那麼無形會占用更多系統資源,畢竟記憶體應該留給更多有需要的地方。

如果傳送端過快或消費端宕機,導致訊息大量積壓,此時訊息還是在記憶體和磁碟各儲存乙份,在訊息大爆發的時候,mq伺服器會撐不住,影響其他佇列的訊息收發,能不能有效的處理這種情況呢。答案惰性佇列

rabbitmq從3.6.0版本開始引入了惰性佇列(lazy queue)的概念。惰性佇列會盡可能的將訊息存入磁碟中,而在消費者消費到相應的訊息時才會被載入到記憶體中,它的乙個重要的設計目標是能夠支援更長的佇列,即支援更多的訊息儲存。當消費者由於各種各樣的原因(比如消費者下線、宕機亦或者是由於維護而關閉等)而致使長時間內不能消費訊息造成堆積時,惰性佇列就很有必要了

預設情況下,當生產者將訊息傳送到rabbitmq的時候,佇列中的訊息會盡可能的儲存在記憶體之中,這樣可以更加快速的將訊息傳送給消費者。即使是持久化的訊息,在被寫入磁碟的同時也會在記憶體中駐留乙份備份。當rabbitmq需要釋放記憶體的時候,會將記憶體中的訊息換頁至磁碟中,這個操作會耗費較長的時間,也會阻塞佇列的操作,進而無法接收新的訊息。雖然rabbitmq的開發者們一直在公升級相關的演算法,但是效果始終不太理想,尤其是在訊息量特別大的時候

惰性佇列會將接收到的訊息直接存入檔案系統中,而不管是持久化的或者是非持久化的,這樣可以減少了記憶體的消耗,但是會增加i/o的使用,如果訊息是持久化的,那麼這樣的i/o操作不可避免,惰性佇列和持久化訊息可謂是「最佳拍檔」。注意如果惰性佇列中儲存的是非持久化的訊息,記憶體的使用率會一直很穩定,但是重啟之後訊息一樣會丟失

佇列具備兩種模式:default和lazy。預設的為default模式,在3.6.0之前的版本無需做任何變更。lazy模式即為惰性佇列的模式,可以通過呼叫channel.queuedeclare方法的時候在引數中設定,也可以通過policy的方式設定,如果乙個佇列同時使用這兩種方式設定的話,那麼policy的方式具備更高的優先順序。如果要通過宣告的方式改變已有佇列的模式的話,那麼只能先刪除佇列,然後再重新宣告乙個新的

設定隊列為惰性佇列的命令:

rabbitmqctl set_policy lazy "

^myqueue$"'

惰性佇列和普通佇列相比,只有很小的記憶體開銷。這裡很難對每種情況給出乙個具體的數值,但是我們可以模擬一下:當傳送1千萬條訊息,每條訊息的大小為1kb,並且此時沒有任何的消費者,那麼普通佇列會消耗1.2gb的記憶體,而惰性佇列只消耗1.5mb的記憶體

據官網測試資料顯示,對於普通佇列,如果要傳送1千萬條訊息,需要耗費801秒,平均傳送速度約為13000條/秒。如果使用惰性佇列,那麼傳送同樣多的訊息時,耗時是421秒,平均傳送速度約為24000條/秒。出現效能偏差的原因是普通佇列會由於記憶體不足而不得不將訊息換頁至磁碟。如果有消費者消費時,惰性佇列會耗費將近40mb的空間來傳送訊息,對於乙個消費者的情況,平均的消費速度約為14000條/秒。

如果要將普通佇列轉變為惰性佇列,那麼我們需要忍受同樣的效能損耗。當轉變為惰性佇列的時候,首先需要將快取中的訊息換頁至磁碟中,然後才能接收新的訊息。反之,當將乙個惰性佇列轉變為普通佇列的時候,和恢復乙個佇列執行同樣的操作,會將磁碟中的訊息批量的匯入到記憶體中。

佇列引數的設定

總結:惰性佇列的存在是為了減少記憶體占用,避免由於記憶體不足而產生的換頁操作。

但對比惰性佇列和普通佇列,如果在記憶體和磁碟均不設限制的話,採用普通佇列的效率會更高,畢竟磁碟再快,對比記憶體也會差乙個數量級。

但如果伺服器的配置捉襟見肘的話,可以考慮惰性佇列的存在,畢竟惰性佇列相比普通佇列,效能差異並不大,在極端情況下還會更好,您覺得呢?

使用lazy queue會有以下幾種搭配

lazy queue 訊息不持久化 , 但是這種模式還是會把訊息放到硬碟裡,ram的使用率會一直很穩定,但是重啟後一樣會丟失訊息

lazy queue 訊息持久化,這種方式無疑是最佳搭配,訊息放到硬碟並且不會因為伺服器重啟而丟失,面對高併發也是從容不已。 麵包和咖啡更配哦

RabbitMQ惰性佇列

惰性佇列會盡可能的將訊息存入磁碟中,而在消費者消費到相應的訊息時才會被載入到記憶體中,它的乙個重要的設計目標是能夠支援更長的佇列,即支援更多的訊息儲存。當消費者由於各種各樣的原因 比如消費者下線 宕機亦或者是由於維護而關閉等 而致使長時間內不能消費訊息造成堆積時,惰性佇列就很有必要了。預設情況下,當...

RabbitMQ之惰性佇列(Lazy Queue)

rabbitmq從3.6.0版本開始引入了惰性佇列 lazy queue 的概念。惰性佇列會盡可能的將訊息存入磁碟中,而在消費者消費到相應的訊息時才會被載入到記憶體中,它的乙個重要的設計目標是能夠支援更長的佇列,即支援更多的訊息儲存。當消費者由於各種各樣的原因 比如消費者下線 宕機亦或者是由於維護而...

Rabbitmq延遲佇列

建立乙個自定義列表 如何建立乙個註腳 注釋也是必不可少的 katex數學公式 新的甘特圖功能,豐富你的文章 uml 圖表 flowchart流程圖 匯出與匯入 你好!這是你第一次使用markdown編輯器所展示的歡迎頁。如果你想學習如何使用markdown編輯器,可以仔細閱讀這篇文章,了解一下mar...