我們知道 RocketMQ 是一款高性能、高可靠的分布式消息中間件,高性能和高可靠是很難兼得的。因為要保證高可靠,那么數據就必須持久化到磁盤上,將數據持久化到磁盤,那么可能就不能保證高性能了。
RocketMQ 在兼容這兩方面做的不錯,先從磁盤說起,現代的磁盤都是高性能的,寫速度並不一定比網絡的數據傳輸速度慢。比如 SSD 固態硬盤在 M.2 NVMe協議下,順序寫的速度可以達到 1500 MB/s,就算是普通磁盤,如果性能比較高的話,順序寫的速度可以達到 450MB/s~600MB/s。
在順序寫的情況下是這速度,但是不人為控制的話,磁盤采用的是隨機寫,在隨機寫的情況下,磁盤的寫入速度急速下降,磁盤的隨機寫速度可能只有幾百KB/s,這遠遠要慢於網絡傳輸速度,所以它並不能滿足高性能的要求。
RocketMQ 在持久化的設計上,采取的是消息順序寫、隨機讀的策略,利用磁盤順序寫的速度,讓磁盤的寫速度不會成為系統的瓶頸。並且采用 MMPP 這種“零拷貝”技術,提高消息存盤和網絡發送的速度。極力滿足 RocketMQ 的高性能、高可靠要求。
上述從硬件的角度聊聊了高性能的保證,這些咱也不懂,還是來看看 RocketMQ 持久化機制的架構圖吧。
在 RocketMQ 持久化機制中,涉及到了三個角色:
- CommitLog:消息真正的存儲文件,所有消息都存儲在 CommitLog 文件中。
- ConsumeQueue:消息消費邏輯隊列,類似數據庫的索引文件。
- IndexFile:消息索引文件,主要存儲消息 Key 與 offset 對應關系,提升消息檢索速度。
咱們逐一聊聊吧,CommitLog 文件是存放消息數據的地方,所有的消息都將存入到 CommitLog 文件中。生產者將消息發送到 RocketMQ 的 Broker 后,Broker 服務器會將消息順序寫入到 CommitLog 文件中,這也就是 RocketMQ 高性能的原因,因為我們知道磁盤順序寫特別快,RocketMQ 充分利用了這一點,極大的提高消息寫入效率。
但是消費者消費消息的時候,可能就會遇到麻煩,每一個消費者只能訂閱一個主題,消費者關心的是訂閱主題下的所有消息,但是同一主題的消息在 CommitLog 文件中可能是不連續的,那么消費者消費消息的時候,需要將 CommitLog 文件加載到內存中遍歷查找訂閱主題下的消息,頻繁的 IO 操作,性能就會急速下降。
為了解決這個問題,RocketMQ 引入了 Consumequeue 文件。Consumequeue 文件可以看作是索引文件,類似於 MySQL 中的二級索引。在存放了同一主題下的所有消息,消費者消費的時候只需要去對應的 Consumequeue 組中取消息即可。Consumequeue 文件不會存儲消息的全量信息,了解 MySQL 索引的話,應該好理解這里,具體存儲的字段,我在上圖已經標注。這樣做可以帶來以下兩個好處:
- 由於 Consumequeue 文件內容小,可以盡可能的保證 Consumequeue 文件全部讀入到內存,提高消費效率。
- Consumequeue 文件也是會持久化的,不存全量信息可以節約磁盤空間。
IndexFile 是 RocketMQ 為消息訂閱構建的索引文件,用來提高根據主題與消息隊列檢索消息的速度,這個就不細說了。
RocketMQ 持久化機制原理差不多就這些了,接下來聊一聊消息數據刷盤吧。
因為操作系統 PAGECACHE 的存在,PageCache是OS對文件的緩存,用於加速對文件的讀寫,所以一般都是先寫入到 PAGECACHE 中,然后再持久化到磁盤上。我們熟悉的其他組件,MySQL、Redis 等都是如此。RocketMQ 也不列外。
在 RocketMQ 中提供了同步刷盤和異步刷盤兩種刷盤方式,可以通過 Broker 配置文中中的 flushDiskType 參數來設置(SYNC_FLUSH、ASYNC_FLUSH)。
異步刷盤方式(默認):消息寫入到內存的 PAGECACHE中,就立刻給客戶端返回寫操作成功,當 PAGECACHE 中的消息積累到一定的量時,觸發一次寫操作,將 PAGECACHE 中的消息寫入到磁盤中。這種方式吞吐量大,性能高,但是 PAGECACHE 中的數據可能丟失,不能保證數據絕對的安全。
同步刷盤方式:消息寫入內存的 PAGECACHE 后,立刻通知刷盤線程刷盤,然后等待刷盤完成,刷盤線程執行完成后喚醒等待的線程,返回消息寫成功的狀態。這種方式可以保證數據絕對安全,但是吞吐量不大。
關於RocketMQ 持久化機制的分享就這些,感謝您的閱讀,希望這篇文章對您的學習或者工作有一點幫助。有收獲的話,也可以幫忙推薦給其他的小伙伴,讓更多的人受益,萬分感謝。
歡迎關注公眾號【互聯網平頭哥】。這里有職場感悟、Java 技術,雖然不高大上,但通俗易懂。今天最好的是明天最低的要求,願你我共同進步。