rocketMq 訊息偏移量 Offset

節日快樂發表於2020-12-21

訊息偏移量 Offset

queue0  offset 0   0-20  offset 4  20-40

糾錯:每條訊息的tag對應的HashCode.

queue1  offset 1  0-20  offset 5  20-40

queue2  offset 2  0-20  offset 6  20-40

queue3  offset 3 0-20  offset 7  20-40

概念

  • message queue 是無限長的陣列,一條訊息進來下標就會漲1,下標就是 offset,訊息在某個 MessageQueue 裡的位置,通過 offset 的值可以定位到這條訊息,或者指示 Consumer 從這條訊息開始向後處理。
  • message queue 中的 maxOffset 表示訊息的最大 offset,maxOffset 並不是最新的那條訊息的 offset,而是最新訊息的 offset+1,minOffset 則是現存在的最小 offset。
  • fileReserveTime=48 預設訊息儲存48小時後,消費會被物理地從磁碟刪除,message queue 的 minOffset 也就對應增長。所以比 minOffset 還要小的那些訊息已經不在 broker上了,就無法被消費

型別(父類是OffsetStore):

  • 本地檔案型別
    • DefaultMQPushConsumer 的 BROADCASTING 廣播模式,各個 Consumer 沒有互相干擾,使用 LocalFileOffsetStore,把 Offset 儲存在本地
  • Broker 代儲存型別
    • DefaultMQPushConsumer 的 CLUSTERING 叢集模式,由 Broker 端儲存和控制 Offset 的值,使用 RemoteBrokerOffsetStore

作用

  • 主要是記錄訊息的偏移量,有多個消費者進行消費
  • 叢集模式下采用 RemoteBrokerOffsetStore,broker 控制 offset 的值
  • 廣播模式下采用 LocalFileOffsetStore,消費端儲存

建議採用 pushConsumer,RocketMQ 自動維護 OffsetStore,如果用另外一種 pullConsumer 需要自己進行維護 OffsetStore

訊息儲存 CommitLog

訊息儲存是由 ConsumeQueue 和 CommitLog 配合完成

  • ConsumeQueue 是邏輯佇列,CommitLog 是真正儲存訊息檔案的,ConsumeQueue 儲存的是指向物理儲存的地址。Topic 下的每個 message queue 都有對應的 ConsumeQueue 檔案,內容也會被持久化到磁碟。預設地址:store/consumequeue/{topicName}/{queueid}/fileName
  • CommitLog:儲存訊息真正內容的檔案。
    • 生成規則:
      • 每個檔案的預設1G =1024 * 1024 * 1024,commitlog 的檔名 fileName,名字長度為20位,左邊補零,剩餘為起始偏移量;比如 00000000000000000000 代表了第一個檔案,起始偏移量為0,檔案大小為1G=1 073 741 824 Byte;當這個檔案滿了,第二個檔名字為00000000001073741824,起始偏移量為1073741824,訊息儲存的時候會順序寫入檔案,當檔案滿了則寫入下一個檔案。
    • 判斷訊息儲存在哪個 CommitLog 上
      • 例如 1073742827 為物理偏移量,則其對應的相對偏移量為 1003 = 1073742827 - 1073741824,並且該偏移量位於第二個 CommitLog。

Broker 裡面一個 Topic 裡面有多個 MesssageQueue,每個 MessageQueue 對應一個 ConsumeQueue,ConsumeQueue 裡面記錄的是訊息在 CommitLog 裡面的物理儲存地址。

IndexFile 訊息索引檔案

    ConsumerQueue是通過偏移量offset去CommitLog檔案中查詢訊息,但實際工作應用中,我們想查詢某條具體的訊息,並不知道offset值,那該怎麼辦呢?那IndexFile作用就來了。
    IndexFile是訊息索引檔案,如果一個生產者傳送的訊息包含key值的話,會使用IndexFile儲存訊息索引,主要用於使用key來查詢訊息。檔案的內容結構如圖

 

 在Broker端,通過Key來計算Hash槽的位置,從而找到Index索引資料。從Index索引中拿到訊息的物理偏移量,最後根據這個物理偏移量,直接到CommitLog檔案中去找就可以了。另外說明下,通過IndexFile來查詢訊息的方法不影響RocketMQ的正常生產-消費流程,它只是查詢定位訊息的方法而已。

 

相關文章