【RocketMQ】源碼系列研究-消息存儲Broker(概要設計)

1.RocketMQ存儲概要設計

    RocketMQ主要存儲的文件包括Comitlog文件、ConsumeQueue文件、IndexFIle文件。RocketMQ將所有主題的消息存儲在同一個文件中,確保消息發送時順序寫文件,盡最大的能力確保消息發送的高性能與吞吐量。但由於消息中間件一般是訂閱機制,這樣便給按照消息主題檢索帶來了極大的不便。爲了提高效率,RocketMQ引入了ConsumeQueu消息隊列文件,每個消息主題包含多個消息消費隊列,每一個消息隊列有一個消息文件。IndexFile索引文件,主要設計理念就是加速消息的檢索性能,根據消息的屬性快速從CommitLog文件中檢索消息

     1.1: commitLog:消息存儲文件,所有消息主題的消息都存儲在CommitLog文件中。

     1.2     ConsumeQueue:消息消費隊列,消息到達CommitLog文件後,將異步轉發到消息消費隊列,供消息消費者消費。

     1.3   IndexFile:消息索引文件,主要存儲消息key與Offset的對應關係

     1.4 事物狀態服務:存儲每條消息的事物狀態

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

 

2.功能描述

Broker是處理消息存儲,轉發等處理的服務器。

 1.Broker以group分開,每個group只允許一個master,若干個slave。

 2.只有master才能進行寫入操作,slave不允許。

3.slave從master中同步數據,同步策略取決於master的配置,可以採用同步雙寫,異步複製兩種。

4.客戶端消費可以從master和slave消費。在默認情況下,消費者都從master消費,在master掛後,客戶端由於從Name Server

中感知到Broker掛掉,就會從salve消費。

5.Broker向所有的Name Server節點建立長鏈接,註冊Topic 信息。

 

3.消息發送存儲流程

代碼結構:

消息存儲實現類:

在store模塊中:

org.apache.rocketmq.store.DefaultMessageStore

這個類在存儲模塊中最重要的一個類:

下面列舉一下核心屬性和方法

1. MessageStoreConfig  messageStoreConfig :消息存儲配置屬性

2.CommitLog commitLog:CommitLog文件的存儲實現類

3.ConcurrentMap<String /**topic */,ConcurrentMap<Integer/*queueId*/,Conssume-Queue>> consumeQueueTable:消息隊列存儲緩存表,按消息主體分組。

4.FlusConsumeQueueService flushConsumeQueueService :消息隊列文件ConsumeQueue刷盤線程。

5. CleanCommitLogService cleanCommitLogService:清除CommitLog文件服務

6.CleanConsumeQueueService cleanConsumeQueueService :清除ConsumeQueue文件服務

7.IndexService indexService :索引文件實現類

8.AllocateMappedFileSErvice allocateMApppedFileService:MappedFile分配服務。

9.ReputMessageServie reputMessageService: CommitLog消息分發,根據CommitLog文件構建ConsumeQueue、IndexFile文件

10.HAService haService:存儲HA機制

11.TransientStorePool transientStorePool: 消息堆內存緩存

12.MessageArrivingListener messagArrivingListener: 消息拉取長輪訓模式消息達到監聽器。

13.BrokerConfig brokerConfig :Broker配置屬性。

14.StoreCheckpoint storeCheckPoint:文件刷盤監測點

15.LinkedList<CommitLogDispacher> dispatcherList:CommitLog文件轉發請求。

消息存儲追蹤入口:

org.apache.rocketmq.store.DefaultMessageStore#putMessage

注意事項:

master節點允許寫入,消息主體長度不能超過256個字符,消息屬性成都不能超過65536個字符。

第二步:

如果消息的延遲級別大於0,將消息的原主題名稱與原消息隊列ID存入消息屬性中,用延遲消息主體SCHEDULE_TOPIC,消息隊列ID更新原消息的主題與隊列,這個是併發消息消費重試關鍵的一步。

代碼中有關於延遲時間的判斷

第三步:

獲取當前可以寫入Commitlog文件,RocketMQ物理文件如下圖:

 

 Commitlog文件存儲目錄爲${ROCKETMQ_HOME}/store/commitlog目錄,mac系統下面可以在用戶根目錄下面找store文件夾

每個文件默認1G,一個文件寫滿後,會再創建另外一個,以該文件中第一個偏移量爲文件名稱,偏移量小於20位用0補齊。如上圖第一個文件的偏移量爲0。MappedFileQueue可以看做是${ROCKETMQ_HOME}/store/commitlog文件夾,而MappedFile則對應該文件夾下一個個的文件。

第四步:

在寫入Commitlog之前,先申請鎖,消息存儲到CommitLog文件是串行的。

第五步:

設置消息的存儲時間,如果mappedFile爲空,表明${ROCKETMQ_HOME}/store/commitlog目錄下不存在任何文件,說明本次消息是第一次消息發送,用偏移量0創建第一個commit文件,。文件名:00000000000000000000

第六步:

將消息追加到MappedFile中。

第七步:

創建全局唯一消息ID,消息ID有16字節

 4字節IP:4字節端口號:8字節消息偏移量

第八步:

獲取改消息在消息隊列的偏移量。CommitLog中保存了當前所有消息隊列的當前待寫入偏移量。

第九步:

根據消息體的長度、主體的長度、屬性的長度結合消息存儲格式計算消息的總長度。

第十步:

如果消息長度+END_FILE_MIN_BLAK_LENGTH大於CommitLog文件的空閒空間,則返回AppendMessageStatus.END_OF_FILE,Broker會重新創建一個新的CommitLog文件來存儲該消息。從這裏可以看出,每個CommitLog文件最少會空閒8個字節,高4字節存儲當前文件剩餘空間,低4字節存儲魔數:CommitLog.BLANK_MAGIC_CODE

十一步:

將消息內容存儲到ByteBuffer中,然後創建AppendMessageResult。這一步只是將消息存儲在MappedFile對應的內存映射Buffer中,並沒有刷寫到磁盤。

十二步:

更新消息隊列邏輯偏移量

十三步:

處理完消息追加邏輯後將釋放putMessageLock鎖。

 

後續會分析:存儲文件組織與內存映射機制

參考資料:《RocketMQ技術內幕》

 

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