RocketMQ知識盤點【貳】_Broker和消息存儲

前文回顧:RocketMQ知識盤點【壹】_Producer和NameServer

 

1.Broker

一個topic擁有多個消息隊列,一個Broker默認爲每個topic創建4個讀隊列和4個寫隊列。多個Broker組成集羣,brokerName相同的多個Broker組成master-slave架構。brokerId爲0的爲master,大於0爲slave。

對於一個Broker,它的存儲目錄是這樣的

下面做逐個解釋。

 

2.消息存儲

 

rocketMq消息存儲文件分爲CommitLog文件、ConsumeQueue文件和IndexFile文件等。其中:

CommitLog存儲所有topic的消息(類似mysql的redo log);

ConsumeQueue爲消息消費隊列,消息到達CommitLog後會異步轉發到這裏供消費者消費;

IndexFile消息索引文件,存儲消息key和offset的關係;

事務狀態服務:存儲每條消息事務狀態;

定時消息服務:因每個延遲隊列對應一個消息消費隊列,這裏存儲每個延遲隊列的拉取進度。

 

2.1 CommitLog

儲存地址爲/store/commitlog目錄,每個文件默認1G,文件寫滿則創建新文件,以該文件第一個消息的全局物理偏移量爲文件名,偏移量小於20用0補齊。

CommitLog文件存儲格式爲,每條消息前4個字節存儲該消息的總長度,之後存儲該消息的其他信息。通過這樣的設計,可以根據偏移量和消息長度查找消息。首先根據偏移量找到所在的物理偏移量文件,然後用offset和文件長度取餘得到文件中的偏移量,從該位置讀取size長度內容即可得到消息。

 

2.2 ConsumeQueue

基於topic模式實現消息消費,因同一topic消息不連續地保存在CommitLog文件中,因此設計這個ConsumeQueue文件,可理解爲索引。單個ConsumeQueue文件默認存儲30W個條目。每個條目的長度是固定的,因此也通過物理偏移量來獲取多個條目。

文件結構:

還可以根據時間戳來查找,基於文件修改時間。

 

2.3 Index文件

IndexHead

  • beginTimestamp:落broker開始時間
  • endTimestamp:落broker截止時間
  • beginPhyoffset:開始偏移量
  • endPhyoffset:截止偏移量
  • hashSlotcount:槽數量
  • indexcount:當前索引總數

slotTable數組

槽位置 = key的hashCode % 槽數量,每個槽記錄的是當前索引數

indexLinkedList鏈表

  • hashCode:key的哈希值
  • pyhoffset:物理偏移地址
  • timedif:落盤時間
  • preIndexNo:hash衝突後上一個索引地址

通過messageId查找,可以直接解析出broker和物理偏移地址,直接查commitLog即可;

通過messageKey查找,則用index文件通過key定位slot,從索引最大值倒序查找,對比hash值和落盤時間返回物理偏移地址,再取commitLog查找。

 

2.4 保存策略

簡單來說分爲同步和異步。

同步是指消息追加到內存映射文件的內存中後,立即刷盤並返回結果,默認超時時間爲5s。

異步是會申請一個和commitLog同樣大小的堆外內存,消息先追加到堆外內存,然後再提交到內存映射文件的內存,最後刷盤。默認10s強制刷一次,每1000條消息強制刷一次。

再多說一句,ConsumeQueue文件和Index文件都是消息保存到CommitLog文件後,通過ReputMessageService線程池異步保存的。

 

2.5 過期文件刪除

3種情況觸發:

1.磁盤空間不足;

2.凌晨4點(deleteWhen)刪除過期文件(默認過期時間爲72小時,fileReservedTime配置);

3.手動觸發。executeDeleteFilesManualy

 

RocketMQ知識盤點【壹】_Producer和NameServer

RocketMQ知識盤點【貳】_Broker和消息存儲

RocketMQ知識盤點【叄】_Consumer

RocketMQ知識盤點【肆】_最佳實踐

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章