當前位置:編程學習大全網 - 源碼下載 - RabbitMQ 消息狀態

RabbitMQ 消息狀態

消息的位置:消息是保存在內存或磁盤上的;

消息是有索引的,索引的位置也是在內存或磁盤上的;

同壹時刻可能內存和磁盤中都有消息或索引.

這些場景是根據隊列類型來決定的.

在rabbit中,隊列中的消息可能會處理以下四種狀態:

alpha:消息內容以及消息在隊列中的位置(消息索引)都保存在內存中;

beta:消息內容只在磁盤上,消息索引只在內存中;

gamma:消息內容只在磁盤上,消息索引在內存和磁盤上都存在;

delta:消息的內容和索引都在磁盤上。

——對於持久化消息,消息內容和消息索引都必須先保存在磁盤上,然後才處於上述狀態中的壹種。即屬性是Durable的消息.

通過狀態的流轉來實現消息位置的變化,目的是在時間和空間中做出合理的取舍.

從內存個CPU的角度來理解就是滿足不同的內存和CPU需求。

alpha最耗內存,但很少消耗CPU,因為直接存儲在內存中;

delta基本不消耗內存,但是要消耗更多的CPU以及磁盤I/O操作(delta需要兩次I/O操作,壹次讀索引,壹次讀消息內容, 所以消息盡可能的發送完立刻被消費;

beta及gamma只需要壹次I/O操作來讀取消息內容)。

gamma更多的是持久化的消息出現的狀態。

在隊列的狀態vqstate(參見 [$RABBIT_SRC/src/rabbit_variable_queue.erl])結構中,存在q1,q2,delta,q3,q4五個隊列(使用 q1~q4使用Erlang的queue模塊,delta存儲結構依賴於消息索引的實現),其中q1,q4只包含alpha狀態的消 息,q2,q3只包含beta和gamma狀態的消息,delta包含delta狀態的消息。

壹般情況下消息會以q1->q2->delta->q3->q4的順序進行狀態變換:消息進入隊列時,處於alpha狀態並保存 在內存中(q1或q4),然後某個時刻發現內存不足,被轉換到beta狀態(q2,q3)(這時候其實有兩個轉換 q1->q2,q4->q3),如果還是內存不足,被轉換到delta狀態(delta)(q2->delta,q3->delta);當從隊 列中消費消息時,會先從處於alpha狀態的內存隊列(q4)中獲取消息,如果q4為空,則從beta狀態的隊列 (q3)中獲取消息,如果q3也為空,則會從delta狀態的消息隊列中讀取消息,並將之轉移到q3。

上述步驟只是個壹般步驟,實際運行時,中間的步驟都是可以跳過的,比如消息可能在壹開始被放在q4隊列 中、q1隊列中的元素會直接跳到q4隊列中(這兩種情況下,q3,delta,q2隊列都為空);當delta隊列為空 時,q2隊列可以直接跳到q3隊列,q1隊列也可以直接跳到q3。

RabbitMQ系統中隊列進程中消息流動邏輯 1.publish(消息的插入)

如果Q3隊列為空,則將消息放入Q4隊列,如果Q3隊列不為空,則將消息放入Q1隊列 2.alpha類型的消息轉化為beta類型的消息(將消息的內容存入磁盤文件)(push_alphas_to_betas函數)

(1).Q1隊列的轉化,如果磁盤文件中的消息數量為0,則將Q1中的消息寫入Q3隊列,如果磁盤文件中的 消息數量不為0,則將Q1中的消息寫入Q2隊列

(2).Q4隊列的轉化,從Q4隊列末端將消息放入到Q3隊列的末端 3.beta類型的消息delta類型的消息(push_betas_to_deltas函數)

(1).從Q3隊列末端將消息的隊列索引存入磁盤文件

(2).將Q2隊列中的消息的隊列索引存入磁盤文件 4.如果Q4,Q3中的消息為空,且磁盤文件中有消息,則將從磁盤中讀取消息,會將delta類型的消息轉化為 beta類型的消息

(1).如果讀取壹個隊列索引磁盤文件後磁盤文件中已經沒有消息,則先將讀取到的消息存入Q3隊列末 尾,然後將Q2隊列中的消息存入Q3隊列的末尾

(2).如果讀取壹個隊列索引磁盤文件後的磁盤文件中還有消息,則將讀取到的消息存入Q3隊列末尾

  • 上一篇:關於股票指數的問題。
  • 下一篇:高曉松直播被痛罵,到底是因為說錯話還是因為太“公知”?
  • copyright 2024編程學習大全網