RocketMQ 消息持久化机制
我們知道 RocketMQ 是一款高性能、高可靠的分布式消息中間件,高性能和高可靠是很難兼得的。因為要保證高可靠,那么數(shù)據(jù)就必須持久化到磁盤上,將數(shù)據(jù)持久化到磁盤,那么可能就不能保證高性能了。
RocketMQ 在兼容這兩方面做的不錯,先從磁盤說起,「現(xiàn)代的磁盤都是高性能的,寫速度并不一定比網(wǎng)絡(luò)的數(shù)據(jù)傳輸速度慢」。比如 SSD 固態(tài)硬盤在 M.2 NVMe協(xié)議下,順序?qū)懙乃俣瓤梢赃_(dá)到 1500 MB/s,就算是普通磁盤,如果性能比較高的話,順序?qū)懙乃俣瓤梢赃_(dá)到 450MB/s~600MB/s。
在順序?qū)懙那闆r下是這速度,但是不人為控制的話,磁盤采用的是隨機(jī)寫,在隨機(jī)寫的情況下,磁盤的寫入速度急速下降,「磁盤的隨機(jī)寫速度可能只有幾百KB/s,這遠(yuǎn)遠(yuǎn)要慢于網(wǎng)絡(luò)傳輸速度,所以它并不能滿足高性能的要求」。
RocketMQ 在持久化的設(shè)計上,采取的是「消息順序?qū)憽㈦S機(jī)讀的策略」,利用磁盤順序?qū)懙乃俣?#xff0c;讓磁盤的寫速度不會成為系統(tǒng)的瓶頸。并且采用 MMPP 這種“零拷貝”技術(shù),提高消息存盤和網(wǎng)絡(luò)發(fā)送的速度。極力滿足 RocketMQ 的高性能、高可靠要求。
在 RocketMQ 持久化機(jī)制中,涉及到了三個角色:
- 「CommitLog」:消息真正的存儲文件,所有消息都存儲在 CommitLog 文件中。
- 「ConsumeQueue」:消息消費(fèi)邏輯隊列,類似數(shù)據(jù)庫的索引文件。
- 「IndexFile」:消息索引文件,主要存儲消息 Key 與 offset 對應(yīng)關(guān)系,提升消息檢索速度。
生產(chǎn)者將消息發(fā)送到 RocketMQ 的 Broker 后,Broker 服務(wù)器會將「消息順序?qū)懭氲?CommitLog 文件中」,這也就是 RocketMQ 高性能的原因,因為我們知道磁盤順序?qū)懱貏e快,RocketMQ 充分利用了這一點(diǎn),極大的提高消息寫入效率。
但是消費(fèi)者消費(fèi)消息的時候,可能就會遇到麻煩,每一個消費(fèi)者只能訂閱一個主題,消費(fèi)者關(guān)心的是訂閱主題下的所有消息,但是同一主題的消息在 CommitLog 文件中可能是不連續(xù)的,那么「消費(fèi)者消費(fèi)消息的時候,需要將 CommitLog 文件加載到內(nèi)存中遍歷查找訂閱主題下的消息,頻繁的 IO 操作,性能就會急速下降」。
為了解決這個問題,RocketMQ 引入了 Consumequeue 文件。「Consumequeue 文件可以看作是索引文件,類似于 MySQL 中的二級索引」。在存放了同一主題下的所有消息,消費(fèi)者消費(fèi)的時候只需要去對應(yīng)的 Consumequeue 組中取消息即可。
「IndexFile」?是 RocketMQ 為消息訂閱構(gòu)建的索引文件,用來提高根據(jù)主題與消息隊列檢索消息的速度
因為操作系統(tǒng) PAGECACHE 的存在,PageCache是OS對文件的緩存,用于加速對文件的讀寫,所以一般都是先寫入到 PAGECACHE 中,然后再持久化到磁盤上。我們熟悉的其他組件,MySQL、Redis 等都是如此。RocketMQ 也不列外。
在 RocketMQ 中提供了「同步刷盤」和「異步刷盤」兩種刷盤方式,可以通過 Broker 配置文中中的 flushDiskType 參數(shù)來設(shè)置(SYNC_FLUSH、ASYNC_FLUSH)。
「異步刷盤方式(默認(rèn))」:消息寫入到內(nèi)存的 PAGECACHE中,就立刻給客戶端返回寫操作成功,當(dāng) PAGECACHE 中的消息積累到一定的量時,觸發(fā)一次寫操作,將 PAGECACHE 中的消息寫入到磁盤中。這種方式「吞吐量大,性能高,但是 PAGECACHE 中的數(shù)據(jù)可能丟失,不能保證數(shù)據(jù)絕對的安全」。
「同步刷盤方式」:消息寫入內(nèi)存的 PAGECACHE 后,立刻通知刷盤線程刷盤,然后等待刷盤完成,刷盤線程執(zhí)行完成后喚醒等待的線程,返回消息寫成功的狀態(tài)。這種方式「可以保證數(shù)據(jù)絕對安全,但是吞吐量不大」。
?
總結(jié)
以上是生活随笔為你收集整理的RocketMQ 消息持久化机制的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据库调优
- 下一篇: 单例模式的5种实现方法及优缺点