RabbitMQ惰性隊列

 惰性隊列會盡可能的將消息存入磁盤中,而在消費者消費到相應的消息時纔會被加載到內存中,它的一個重要的設計目標是能夠支持更長的隊列,即支持更多的消息存儲。當消費者由於各種各樣的原因(比如消費者下線、宕機亦或者是由於維護而關閉等)而致使長時間內不能消費消息造成堆積時,惰性隊列就很有必要了。

 

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

 

        惰性隊列會將接收到的消息直接存入文件系統中,而不管是持久化的或者是非持久化的,這樣可以減少了內存的消耗,但是會增加I/O的使用,如果消息是持久化的,那麼這樣的I/O操作不可避免,惰性隊列和持久化消息可謂是“最佳拍檔”。注意如果惰性隊列中存儲的是非持久化的消息,內存的使用率會一直很穩定,但是重啓之後消息一樣會丟失。

 

        隊列具備兩種模式:default 和 lazy。默認的爲default模式,lazy模式即爲惰性隊列的模式,可以通過調用channel.queueDeclare方法的時候在參數中設置,也可以通過Policy的方式設置,如果一個隊列同時使用這兩種方式設置的話,那麼Policy的方式具備更高的優先級。如果要通過聲明的方式改變已有隊列的模式的話,那麼只能先刪除隊列,然後再重新聲明一個新的。

 

        在隊列聲明的時候可以通過“x-queue-mode”參數來設置隊列的模式,取值爲“default”和“lazy”。

 

        惰性隊列和普通隊列相比,只有很小的內存開銷。這裏很難對每種情況給出一個具體的數值,但是我們可以類比一下:當發送1千萬條消息,每條消息的大小爲1KB,並且此時沒有任何的消費者,那麼普通隊列會消耗1.2GB的內存,而惰性隊列只消耗1.5MB的內存。

 

        據官網測試數據顯示,對於普通隊列,如果要發送1千萬條消息,需要耗費801秒,平均發送速度約爲13000條/秒。如果使用惰性隊列,那麼發送同樣多的消息時,耗時是421秒,平均發送速度約爲24000條/秒。出現性能偏差的原因是普通隊列會由於內存不足而不得不將消息換頁至磁盤。如果有消費者消費時,惰性隊列會耗費將近40MB的空間來發送消息,對於一個消費者的情況,平均的消費速度約爲14000條/秒。

 

        如果要將普通隊列轉變爲惰性隊列,那麼我們需要忍受同樣的性能損耗。當轉變爲惰性隊列的時候,首先需要將緩存中的消息換頁至磁盤中,然後才能接收新的消息。反之,當將一個惰性隊列轉變爲普通隊列的時候,和恢復一個隊列執行同樣的操作,會將磁盤中的消息批量的導入到內存中。

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