91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

RabbitMQ存儲原理和隊列結構是什么

發布時間:2021-12-09 15:24:48 來源:億速云 閱讀:215 作者:柒染 欄目:大數據

本篇文章為大家展示了RabbitMQ存儲原理和隊列結構是什么,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。

存儲原理

首先確認一個點,持久化和非持久化的消息都會落地磁盤,區別在于持久化的消息一定會寫入磁盤(并且如果可以在內存中也會有一份),而非持久化的消息只有在內存吃緊的時候落地磁盤。兩種類型消息的落盤都是在RabbitMQ的持久層中完成的。

RabbitMQ的持久層只是一個邏輯上的概念,實際包含兩個部分:

  • 隊列索引(rabbit_queue_index):負責維護隊列中落盤消息的信息,包括消息的存儲地點、是否己被交付給消費者、是否己被消費者ack等。 每個隊列都有與之對應的一個rabbit_queue_index

  • 消息存儲(rabbit_msg_store):以鍵值對的形式存儲消息,它被所有vhost中的隊列共享,在每個vhost中有且只有一個。rabbit_msg_store具體還可以分為 msg_store_persistent和msg_store_transient,msg_store_persistent負責持久化消息的持久化,重啟后消息不會丟失;msg_store_transient負責 非持久化消息的持久化,重啟后消息會丟失。

消息(包括消息體、屬性和headers)可以直接存儲在rabbit_queue_index中,也可以被保存在rabbit_msg_store中。

最佳的配備方式是較小的消息存儲在rabbit_queue_index中而較大的信息則存儲在rabbit_msg_store中。消息大小的參數可以通過queue_index_embed_mgs_below來配置,默認大小4096,單位B。

rabbit_queue_index中以順序的段文件來開始存儲,后綴為".idx",每個段文件中包含固定的SEGMENT_ENTRY_COUNT條記錄,SEGMENT_ENTRY_COUNT默認值是16384。

經過rabbit_msg_store處理的所有消息都會以追加的方式寫入到文件中,當一個文件的大小超過指定的限制(filesizelimit)后,關閉這個文件再創建一個新的文件以供新的消息寫入。文件名(文件后綴是".rdq")從0開始進行累加,因此文件名最小的文件也是最老的文件。在進行消息的存儲時,RabbitMQ會在ETS(Erlang Term Storage)表中記錄消息在文件中的位置映射(Index)和文件的相關信息(FileSummary)。

在讀取消息的時候,先根據消息的ID(msg id)找到對應存儲的文件,如果文件存在并且未被鎖住,則直接打開文件,從指定位置讀取消息的內容。如果文件不存在或者被鎖住了,則發送請求由rabbit_msg_store進行處理。

消息刪除是只是刪除ETS表中該消息的相關信息,同時更新消息對應的存儲文件的相關信息。執行消息刪除操作時,并不立即對文件中的消息進行刪除,也就是說消息依然在文件中,僅僅是被標識為垃圾數據而已。一個文件中都是垃圾數據時可以將這個文件刪除。當檢測到前后兩個文件中的有效數據可以合并在一個文件中,并且所有的垃圾數據的大小和所有文件(至少有3個文件存在的情況下)的數據大小的比值超過設置的閥值GARBAGE FRACTION(默認值為0.5)時才會觸發垃圾回收將兩個文件合并。

隊列結構

通常隊列由rabbit_amqpqueue_process和backing_queue兩部分組成:

  • rabbit_amqpqueue_process:負責協議相關的消息處理(即接收生產者發布的消息、向消費者交付消息、處理消息的確認(包括生產端的confirm和消費端的ack))等

  • backing_queue:消息存儲的具體形式和引擎,并向rabbit_amqpqueue_process提供接口以供調用

如果消息發送的隊列是空的且隊列有消費者,該消息不會經過該隊列直接發往消費者,如果無法直接被消費,則需要將消息暫存入隊列,以便重新投遞。消息在存入隊列后,主要有以下幾種狀態:

  • alpha:消息內容(包括消息體、屬性和headers)和消息索引都存在內存中

  • beta:消息內容保存在磁盤中,消息索引都存在內存中

  • gamma:消息內容保存在磁盤中,消息索引在磁盤和內存中都存在

  • delta:消息內容和消息索引都在磁盤中

持久化的消息,消息內容和消息索引必須都保存在磁盤中,才會處于上面狀態中的一種,gamma狀態只有持久化的消息才有這種狀態。

對于沒有設置優先級和鏡像的隊列來說,backing_queue的默認實現是rabbit_variable_queue,其內部通過5個子隊列來體現消息的各個狀態:

  • Q1:只包含alpha狀態的消息

  • Q2:包含beta和gamma的消息

  • Delta:包含delta的消息

  • Q3:包含beta和gamma的消息

  • Q4:只包含alpha狀態的消息

消息的狀態一般變更方向是Q1->Q2->Delta->Q3->Q4,大體是從內存到磁盤然后再到內存中。RabbitMQ存儲原理和隊列結構是什么消費者消費消息也會引起消息狀態的轉換。

  1. 消費者消費時先從Q4獲取消息,如果獲取成功則返回。

  2. 如果Q4為空,則從Q3中獲取消息,首先判斷Q3是否為空,如果為空返回隊列為空,即此時隊列中無消息

  3. 如果Q3不為空,取出Q3的消息,然后判斷Q3和Delta中的長度,如果都為空,那么Q2、Delta、Q3、Q4都為空,直接將Q1中的消息轉移至Q4,下次直接從Q4中讀取消息

  4. 如果Q3為空,Delta不為空,則將Delta中的消息轉移至Q3中,下次直接從Q3中讀取。

  5. 在將消息從Delta轉移至Q3的過程中,是按照索引分段讀取,首先讀取某一段,然后判斷讀取的消息個數和Delta消息的個數,如果相等,判定Delta已無消息,直接將讀取 Q2和讀取到消息一并放入Q3,如果不相等,僅將此次讀取的消息轉移到Q3。

通常在負載正常時,如果消息被消費的速度不小于接收新消息的速度,對于不需要保證可靠不丟失的消息來說,極有可能只會處于alpha狀態。對于durable屬性設置為true的消息,它一定會進入gamma狀態,并且在開啟publisher confirm機制時,只有到了gamma狀態時才會確認該消息己被接收,若消息消費速度足夠快、內存也充足,這些消息也不會繼續走到下一個狀態。

惰性隊列

惰性隊列會將接收到的消息直接存入文件系統中,而不管是持久化的或者是非持久化的,這樣可以減少了內存的消耗,但是會增加I/0的使用,如果消息是持久化的,那么這樣的I/0操作不可避免,惰性隊列和持久化的消息可謂是"最佳拍檔"。

隊列具備兩種模式:default和lazy。在隊列聲明的時候可以通過x-queue-mode參數來設置隊列的模式,取值為default和lazy。對應的 Policy設置方式為:

  rabbitmqctl set_policy lazy "^myQueue$" '{"queue-mode":"lazy"}' --apply-to queue

上述內容就是RabbitMQ存儲原理和隊列結構是什么,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

含山县| 江门市| 涿州市| 永修县| 七台河市| 孝昌县| 静海县| 平定县| 米林县| 贡山| 阿合奇县| 丰宁| 镇远县| 都江堰市| 达州市| 双流县| 广德县| 汪清县| 景宁| 衡东县| 台北县| 社旗县| 闸北区| 思南县| 五大连池市| 洞头县| 南华县| 淮安市| 安阳市| 阿克| 汽车| 车致| 辉县市| 枝江市| 武宣县| 珲春市| 延津县| 玉环县| 二连浩特市| 郁南县| 山东省|