RocketMQ -- 刷盤機制

大軍發表於2022-03-26

上面講了訊息到記憶體的過程,為了訊息不丟失,是需要持久化到磁碟上的,這裡又分為同步刷屏和非同步刷屏。

在記憶體裡處理後,就開始釋放鎖,處理完的結果叫result。所以到了刷屏的階段,可能會有一個或者多個的result需要處理。

image.png

同步刷盤

同步刷盤的服務,也是一個執行緒,專門用來處理這些result。他維護著requestsWrite和requestsRead的連結串列。requestsWrite是放需要處理的result,requestsRead是放準備處理的result。

image.png

每個result需要同步刷盤服務處理的時候,都會放入requestsWrite,由於requestsWrite並不是執行緒安全的,所以這裡也需要加鎖和釋放鎖的操作。

image.png

上面提過,這個服務也是一個執行緒,這個執行緒就是用來處理requestsRead的。

這個執行緒每處理完requestsRead就會等待最多10ms的時間,直至被重新喚醒。

所以requestsWrite有資料的時候,就會喚醒這個執行緒,這個執行緒就會把requestsWrite和requestsRead裡的資料進行交換。

由於寫入requestsWrite是併發的,所以交換的時候,可能會有多個result到requestsRead裡。

image.png

交換完後,就開始把requestsRead裡的資料進行落盤,這個執行緒並不影響requestsWrite的寫入。

非同步刷盤

非同步刷盤,簡單的說,就是不等落盤就直接返回。

同樣的,非同步刷盤也有一個執行緒的服務,每隔一段時間就開始進行刷盤。但是這裡也有一個小區別,就是是否開啟堆外記憶體機制。

如果沒有開啟,那訊息是追加到與物理檔案對映的記憶體中,然後寫入到磁碟。

如果開啟了,那會建立一個一個commitlog一樣大小的堆外記憶體,所以訊息會追加到這個堆外記憶體中,然後是提交到與物理檔案對映的記憶體中,最後寫入到磁碟。

mmap記憶體對映

為了提高效能,RocketMQ通過記憶體對映檔案來提高IO訪問效能。

所謂記憶體對映,就是實體地址和記憶體地址做了一個對映,實際上並沒有把資料拷貝到記憶體中。

記憶體對映是有大小限制的,在1.5到2G之間,所以Commitlog的檔案大小為1G,ConsumeQueue的檔案大小為5.72M。

相關文章