动态

详情 返回 返回

【RocketMQ 消息中間件】RocketMQ篇之-消息存儲 為什麼性能高 CommitLog 刷盤機制 同步 異步 - 动态 详情

RocketMQ篇之-消息存儲

RocketMQ作為一款分佈式消息中間件,高可靠性是其最重要的特性之一。
所以需要將消息進行持久化存儲,以保證消息不丟失。

RocketMQ的消息存儲是RocketMQ的核心組件之一,負責消息的存儲和傳輸。RocketMQ的消息存儲主要包括CommitLog、ConsumeQueue、IndexFile、Checkpoint等幾個部分。

(前置)消息存儲交互流程

  1. 生產者發送消息MQ;
  2. MQ將消息存到存儲系統;
  3. 返回消息存儲結果;
  4. 消費者從存儲系統拉取消息,消費消息;
  5. 消費者消費成功,返回消費結果;
  6. 存儲系統刪除消息。

img.png

(一)存儲系統

在上面的流程中,存儲系統是RocketMQ的核心組件之一,負責消息的讀寫。

存儲系統有以下幾種選擇:

  1. 內存存儲等;
  2. 關係型數據庫存儲;
  3. 文件存儲;

在RocketMQ中,使用的是文件存儲。

1. 內存存儲

內存存儲是一種高性能的存儲方式,但是內存存儲的數據是不穩定的,一旦斷電,數據就會丟失。即便是以Redis為代表的內存數據庫,也無法保證數據的持久化,在持久化方面,還是選擇文件存儲。所以對消息來説,內存存儲是不適合的。

2. 關係型數據庫存儲

關係型數據庫存儲是一種常見的存儲方式,像MySQL、Oracle等都可以作為消息存儲。阿帕奇的ActiveMQ、Pulsar等都是使用關係型數據庫作為消息存儲。但其實關係型數據庫底層也是文件存儲,所以對比直接使用文件存儲,關係型數據庫存儲的性能會有所下降。
img_1.png

3. 文件存儲

文件存儲是一種常見的存儲方式,像Kafka、RocketMQ、RabbitMQ等都是使用文件存儲。文件存儲的優點是性能高,穩定性好,適合消息存儲。
img_2.png

(二)消息的存儲和發送

1. 消息存儲(順序寫入)

磁盤的讀寫速度雖然比內存慢,但是和網絡IO相比,磁盤的讀寫速度還是很快的。現在的磁盤讀寫速度已經達到了幾百MB/s甚至上千MB/s,所以對於消息存儲來説,磁盤的讀寫速度是足夠的。
但是在隨機讀寫方面,磁盤的性能就會有比較嚴重的下降,所以RocketMQ的消息存儲是順序寫入的,這樣可以提高磁盤的讀寫性能。

2. 消息發送(零拷貝)

消息的發送,需要將磁盤內的數據發送到網絡中,在這個過程中,會涉及到系統的內核態和用户態的切換,這個過程是比較耗時的。

把磁盤數據發送到網絡中,需要經過以下幾個步驟:

  1. 從磁盤中讀取數據;
  2. 將讀取的數據發送到網絡中;

看似只有兩個步驟,但是在實際的操作中,還會涉及到內核態和用户態的切換和數據複製等操作:

  1. 從磁盤中讀取數據,磁盤複製 -> 內核態的緩衝區;
  2. 內核態的緩衝區複製 -> 用户態的緩衝區;
  3. 將數據發送到網絡中,從用户態的緩衝區複製 -> 網絡驅動的內核態緩衝區;
  4. 網絡驅動的內核態緩衝區複製 -> 網絡中;

重要‼️:RocketMQ通過mmap的方式將磁盤文件映射到內存中,這樣可以減少內核態和用户態的切換,減少數據的複製,提高性能,也就是所謂的零拷貝。

img_3.png
img_4.png

(三)存儲文件結構

img_5.png
在RocketMQ中,有三個重要的文件類型:commitlog、consumequeue和index文件。它們分別有不同的用途和存儲內容。

1. CommitLog

用途:

CommitLog文件是RocketMQ存儲消息的核心文件。所有的消息首先都會被寫入到CommitLog文件中。
它以順序寫的方式保存消息,以確保寫入的高性能和可靠性。

存儲內容:

CommitLog文件存儲的是消息的完整內容,包括消息的元數據(如消息ID、主題、隊列ID等)和消息體。

聯繫:

所有消息最初都會寫入到CommitLog文件中,然後再由消息服務組件(例如:ConsumeQueue和IndexFile)進行進一步的處理。

2. ConsumeQueue

用途:

ConsumeQueue是RocketMQ的消費者隊列文件,主要用於提高消息消費的效率。
它相當於消息的索引文件,消費者可以通過ConsumeQueue快速定位到需要消費的消息在CommitLog中的位置。

存儲內容:

ConsumeQueue文件存儲的是消息在CommitLog中的物理偏移量、消息大小和消息的標籤哈希值。

聯繫和區別:

ConsumeQueue是從CommitLog文件中生成的,用於加速消息消費。它只存儲消息的索引信息,而不是消息的完整內容

3. IndexFile

用途:

IndexFile是RocketMQ的索引文件,主要用於通過消息的索引(例如:消息的唯一標識符Key)快速查找消息。
它實現了基於哈希的索引機制,支持消息的快速檢索。

存儲內容:

IndexFile文件存儲的是消息的Key(唯一標識符)、消息的物理偏移量和消息的存儲時間。

聯繫和區別:

IndexFile也是從CommitLog文件中生成的,但它的目的是為了提供消息的快速檢索功能。
與ConsumeQueue不同,IndexFile是通過消息的Key來查找消息,而不是通過主題和隊列。ConsumeQueue是通過消息的主題和隊列ID來查找消息。

總結

CommitLog:RocketMQ中存儲所有消息的核心文件,保存消息的完整內容。
ConsumeQueue:消費者隊列文件,用於加速消息消費,存儲消息的索引信息。
IndexFile:索引文件,用於快速檢索消息,存儲消息的Key和物理偏移量。
這三種文件共同協作,確保了RocketMQ的高性能和高可靠性。CommitLog負責消息的存儲,ConsumeQueue提高了消息的消費效率,而IndexFile則提供了消息的快速檢索能力。

(四)刷盤機制

RocketMQ的消息存在磁盤中,這樣能保證在斷電後消息不會丟失。
在消息寫入磁盤的過程中,有兩種刷盤機制:同步刷盤和異步刷盤。

img_6.png

1. 同步刷盤

同步刷盤是指在消息寫入磁盤後,需要等待磁盤的寫入操作完成後,才返回寫入成功的結果。

同步刷盤的優點是數據安全,可以保證消息不會丟失。但是同步刷盤的缺點是性能較差,因為需要等待磁盤的寫入操作完成後才能返回結果。

2. 異步刷盤

異步刷盤是指在消息寫入磁盤後,不需要等待磁盤的寫入操作完成,可以立即返回寫入成功的結果,然後由後台線程負責將數據刷盤到磁盤中。

異步刷盤的優點是性能較好,因為不需要等待磁盤的寫入操作完成,可以立即返回結果。但是異步刷盤的缺點是數據不安全,可能會丟失部分消息。

選擇

在實際的應用中,可以根據業務的需求選擇合適的刷盤機制。如果對數據的安全性要求較高,可以選擇同步刷盤;如果對性能要求較高,可以選擇異步刷盤。

總結

RocketMQ的消息存儲是RocketMQ的消息持久化的方式,保證消息不會丟失。
我們講了以下幾部分相關的內容:

  1. 存儲系統的選擇,選擇了文件存儲。
  2. 消息的存儲和發送,通過順序寫入和零拷保證性能。(也是RocketMQ為什麼高性能的主要原因)
  3. 存儲文件結構,CommitLog、ConsumeQueue和IndexFile。
  4. 刷盤機制,同步刷盤和異步刷盤。

這些內容是RocketMQ消息存儲的核心內容,對於理解RocketMQ的消息存儲機制非常重要。希望本文對你有所幫助,如果有任何問題,歡迎留言討論。

user avatar mannayang 头像 king_wenzhinan 头像 xiaoniuhululu 头像 journey_64224c9377fd5 头像 u_15702012 头像 jiangyi 头像 lenve 头像 chenjiabing666 头像 devlive 头像 javaedge 头像 xiongshihubao 头像 pottercoding 头像
点赞 39 用户, 点赞了这篇动态!
点赞

Add a new 评论

Some HTML is okay.