日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

深入理解RocketMQ是如何做到高性能的?

發布時間:2025/3/15 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深入理解RocketMQ是如何做到高性能的? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1、RocketMQ的核心Broker

對rocketmq稍有了解的同學,都知道它主要由4部分組成,Producer、Consumer、Broker、NameServer。

Broker作為Rocket MQ的核心,提供了強大的數據存儲能力,可以把億萬級的消息存儲在服務器磁盤上。它決定了生產者寫入的吞吐量,決定了消息不能丟失,決定了消費者消費消息的吞吐量。

2、消息寫入磁盤文件:CommitLog

當生產者的消息發送到一個Broker上的時候,它接收到了一條消息,會對這個消息做什么處理?

首先第一步,他會把這個消息直接寫入磁盤上的一個日志文件,沒錯就是磁盤文件,它叫做CommitLog,直接順序寫入這個文件,如下圖。

圖1?消息順序寫入CommitLog文件

這個CommitLog文件默認大小是1G,如果消息很多的話,可能會創建很多個CommitLog文件。

CommitLog文件的文件名長度為20位,左邊補零,剩余為起始偏移量,比如00000000000000000000代表了第一個文件,起始偏移量為0,文件大小為1G=1073741824;當第一個文件寫滿了,第二個文件為00000000001073741824,起始偏移量為1073741824,以此類推。

圖2?CommitLog文件

Broker收到消息后,直接追加到這個文件的末尾。

3、消息的偏移量寫入磁盤文件:ConsumeQueue

我們知道每個Topic可能對應了多個Queue,那么這些Queue在Broker中是如何體現的呢?

其實在Broker中,每個Topic下的每個Queue都會對應一些列的ConsumeQueue文件。

圖3 Broker本地存儲文件

就是在Broker磁盤上,會有下面這種格式的一些列文件:

~/store/consumequeue/{topic}/{queueId}/{fileName}

{topic}指代的就是某個Topic,{queueId}指代的就是某個MessageQueue。

然后存儲在這臺Broker機器上的Topic下的一個MessageQueue,他有很多的ConsumeQueue文件,這個ConsumeQueue文件里存儲的是一條消息對應在CommitLog文件中的offset偏移量

這點比較重要,ConsumeQueue不存儲真實的消息數據,只存消息數據在CommitLog文件中的偏移量。

假設有一個Topic,他有4個Queue,然后分布在兩臺Broker機器上,每臺Broker機器會存儲兩個Queue。

此時生產者選擇對其中一個Queue寫入了一條消息,此時消息會發送到Broker上。

然后然后Broker會把這個消息寫入CommitLog文件中,同時會把消息的偏移量寫入兩個ConsumeQueue中,ConsumeQueue0和ConsumeQueue1。它們分別對應著Topic里的Queue0和Queue1。

圖4?消息偏移量寫入ConsumeQueue文件中

也就是說,Topic下的Queue0和Queue1就放在這個Broker機器上,而它們每個在磁盤上對應了一個ConsumeQueue文件,所以就是Queue0對應著Broker磁盤上的ConsumeQueue0,Queue1對應著磁盤上的ConsumeQueue1。

假設Queue的名字叫做:TopicOrderInfo,Queue0的id是0,Queue1的id是1,那么此時在Broker磁盤上應該有如下兩個路徑的文件:

~/store/consumequeue/TopicOrderInfo/0/ConsumeQueue0文件

~/store/consumequeue/TopicOrderInfo/1/ConsumeQueue1文件

圖5?ConsumeQueue本地磁盤文件

然后,當你的Broker收到一條消息寫入了CommitLog之后,其實他同時會將這條消息在CommitLog中的物理位置,也就是一個文件偏移量(offset),寫入到這條消息所屬的Queue對應的ConsumeQueue文件中去。

ConsumeQueue文件存在的目的就是可以快速定位到消息真實的物理位置,在ConsumeQueue中存儲的每條數據不只是消息在CommitLog中的offset偏移量,還包含了消息的長度,以及tag hashcode,一條數據是20個字節,每個ConsumeQueue文件保存30萬條數據,所以計算下來每個文件是5.72MB。

需要注意的是每個Topic的每個Queue都對應了Broker機器上的多個ConsumeQueue文件,保存了這個MessageQueue的所有消息在CommitLog文件中的物理位置,也就是offset偏移量。

4、RocketMQ是如何提升CommitLog寫入性能的?

CommitLog作為存儲消息的核心所在,關乎著整個消息隊列的吞吐量。那么Broker是如何提升整個過程的性能的呢?

Broker是基于OS操作系統的PageCache和順序寫兩個機制,來提升寫入CommitLog文件的性能的。

首先Broker是以順序的方式將消息寫入CommitLog磁盤文件的,也就是每次寫入就是在文件末尾追加一條數據就可以了,對文件進行順序寫的性能要比對文件隨機寫的性能提升很多。

另外,消息寫入CommitLog文件的時候,并不是直接寫入磁盤文件的,而是先進入OS的PageCache內存緩存中,然后再由OS的后臺線程選一個時間,異步化的將OS PageCache內存緩沖中的數據刷入底層的磁盤文件。

圖6?異步刷盤CommitLog文件

在采用磁盤文件順序寫+OS PageCache寫入+OS異步刷盤的策略,基本上可以讓消息寫入CommitLog的性能接近直接寫入內存,所以正是如此,才可以讓Broker高吞吐的處理每秒大量的消息寫入。

5、異步刷盤的利弊

很多時候魚和熊掌不可兼得,我們充分提升性能的同時,就會犧牲一些高可用性。

如果生產者認為消息寫入成功了,但是實際上那條消息此時是在Broker機器上的os cache中的,如果此時Broker直接宕機,那么是不是os cache中的這條數據就會丟失了?

所以異步刷盤的的策略下,可以讓消息寫入吞吐量非常高,但是可能會有數據丟失的風險。

所以rocketmq提供了同步刷盤,讓使用者可選擇。如果你使用同步刷盤模式的話,那么生產者發送一條消息出去,broker收到了消息,必須直接強制把這個消息刷入底層的物理磁盤文件中,然后才會返回ack給producer,此時你才知道消息寫入成功了。

但是如果你強制每次消息寫入都要直接進入磁盤中,必然導致每條消息寫入性能急劇下降,導致消息寫入吞吐量急劇下降,但是可以保證數據不會丟失。具體如何選擇,還需要看你的業務場景。

6、總結

這篇文章主要講broker最為核心的數據存儲機制,希望伙伴們不只是記住,也要理解思考,為什么這樣設計,自己的項目中是否有可以借鑒學習的地方。

有道無術,術可成;有術無道,止于術

歡迎大家關注Java之道公眾號

好文章,我在看??

總結

以上是生活随笔為你收集整理的深入理解RocketMQ是如何做到高性能的?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。