Apache Kafka 核心組件和流程-日誌管理器-設計-原理(入門教程輕鬆學)

本入門教程,涵蓋Kafka核心內容,通過實例和大量圖表,幫助學習者理解,任何問題歡迎留言。

目錄:

上一節介紹了協調器。協調器主要負責消費者和kafka集羣間的協調。那麼消費者消費時,如何定位消息呢?消息是如何存儲呢?本節將爲你揭開答案。

3 日誌管理器

3.1 日誌的存儲

Kafka的消息以日誌文件的形式進行存儲。不同主題下不同分區的消息是分開存儲的。同一個分區的不同副本也是以日誌的形式,分佈在不同的broker上存儲。

這樣看起來,日誌的存儲是以副本爲單位的。在程序邏輯上,日誌確實是以副本爲單位的,每個副本對應一個log對象。但實際在物理上,一個log又劃分爲多個logSegment進行存儲。

舉個例子,創建一個topic名爲test,擁有3個分區。爲了簡化例子,我們設定只有1個broker,1個副本。那麼所有的分區副本都存儲在同一個broker上。

第二章中,我們在kafka的配置文件中配置了log.dirs=/tmp/kafka-logs。此時在/tmp/kafka-logs下面會創建test-0,test-1,test-2三個文件夾,代表三個分區。命名規則爲「topic名稱-分區編號」

我們看test-0這個文件夾,注意裏面的logSegment並不代表這個文件夾,logSegment代表邏輯上的一組文件,這組文件就是.log、.index、.timeindex這三個不同文件擴展名,但是同文件名的文件。

  1. .log存儲消息
  2. .index存儲消息的索引
  3. .timeIndex,時間索引文件,通過時間戳做索引。

這三個文件配合使用,用來保存和消費時快速查找消息。

剛纔說到同一個logSegment的三個文件,文件名是一樣的。命名規則爲.log文件中第一條消息的前一條消息偏移量,也稱爲基礎偏移量,左邊補0,補齊20位。比如說第一個LogSegement的日誌文件名爲00000000000000000000.log,假如存儲了200條消息後,達到了log.segment.bytes配置的閾值(默認1個G),那麼將會創建新的logSegment,文件名爲00000000000000000200.log。以此類推。另外即使沒有達到log.segment.bytes的閾值,而是達到了log.roll.ms或者log.roll.hours設置的時間觸發閾值,同樣會觸發產生新的logSegment。

 

3.2 日誌定位

日誌定位也就是消息定位,輸入一個消息的offset,kafka如何定位到這條消息呢?

日誌定位的過程如下:

1、根據offset定位logSegment。(kafka將基礎偏移量也就是logsegment的名稱作爲key存在concurrentSkipListMap中)

2、根據logSegment的index文件查找到距離目標offset最近的被索引的offset的position x。

3、找到logSegment的.log文件中的x位置,向下逐條查找,找到目標offset的消息。

結合下圖中例子,我再做詳細的講解:

這裏先說明一下.index文件的存儲方式。.index文件中存儲了消息的索引,存儲內容是消息的offset及物理位置position。並不是每條消息都有自己的索引,kafka採用的是稀疏索引,說白了就是隔n條消息存一條索引數據。這樣做比每一條消息都建索引,查找起來會慢,但是也極大的節省了存儲空間。此例中我們假設跨度爲2,實際kafka中跨度並不是固定條數,而是取決於消息累積字節數大小。

例子中consumer要消費offset=15的消息。我們假設目前可供消費的消息已經存儲了三個logsegment,分別是00000000000000000,0000000000000000010,0000000000000000020。爲了講解方便,下面提到名稱時,會把前面零去掉。

下面我們詳細講一下查找過程。

  1. kafka收到查詢offset=15的消息請求後,通過二分查找,從concurrentSkipListMap中找到對應的logsegment名稱,也就是10。
  2. 從10.index中找到offset小於等於15的最大值,offset=14,它對應的position=340
  3. 從10.log文件中物理位置340,順序往下掃描文件,找到offset=15的消息內容。

可以看到通過稀疏索引,kafka既加快了消息查找的速度,也顧及了存儲的開銷。

下一步:開始kafka核心組件和流程--副本管理器的學習