Kafka檔案結構
Kafka 中消息是以 topic 進行分類的,生産者生産消息,消費者消費消息,都是面向 topic
的。topic 是邏輯上的概念,而 partition 是實體上的概念,每個 partition 對應于一個 log 文
件,該 log 檔案中存儲的就是 producer 生産的資料。Producer 生産的資料會被不斷追加到該
log 檔案末端,且每條資料都有自己的 offset(偏移量)。消費者組中的每個消費者,都會實時記錄自己消費到了哪個 offset,以便出錯恢複時,從上次的位置繼續消費。
由于生産者生産的消息會不斷追加到 log 檔案末尾,為防止 log 檔案過大導緻資料定位效率低下,Kafka 采取了 分片和 索引機制(預設産生1G資料時候進行分片),将每個 partition 分為多個 segment。每個 segment對應兩個檔案--“.index”檔案和“.log”檔案。這些檔案位于一個檔案夾下,該檔案夾的命名規則為:topic 名稱+分區序号。例如,first 這個 topic 有三個分區,則其對應的檔案夾為 first-0,first-1,first-2。
index 和 log 檔案以目前 segment 的第一條消息的 offset 命名。如下所示:
00000000000000000000.index
00000000000000000000.log
00000000000000170410.index
00000000000000170410.log
00000000000000239430.index
00000000000000239430.log
我們用下面這張圖來記住剛才所描述的問題:
其中 index 檔案和 log檔案的結構示意圖如下圖所示:
“.index”檔案存儲大量的索引資訊,“.log”檔案存儲大量的資料,索引檔案中的中繼資料指向對應資料檔案中 message 的實體偏移位址。
具體的kafka是如何通過offset定位一條消息的呢?
如下圖所示:
index檔案的序号就是message在日志檔案中的相對偏移量
OffsetIndex是稀疏索引,也就是說不會存儲所有的消息的相對offset和position
消息檢索的過程,以這個partition目錄下面,00000000001560140916為例:
定位offset為1560140921的message
①定位到具體的segment日志檔案,采用二分法先定位到index索引檔案
由于log日志檔案的檔案名是這個檔案中第一條消息的offset-1。
是以可以根據offset定位到這個消息所在日志檔案:00000000001560140916.log
這個過程是利用二分法進行查找的。
②計算查找的offset在日志檔案的相對偏移量
segment檔案中第一條消息的offset = 1560140917
計算message相對偏移量:
需要定位的offset - segment檔案中第一條消息的offset + 1 = 1560140921 - 1560140917 + 1 = 5
查找index索引檔案, 可以定位到該消息在日志檔案中的偏移位元組為456。
綜上,直接讀取檔案夾00000000001560140916.log中偏移456位元組的資料即可。
1560140922 -1560140917 +1 = 6 如果查找的offset在日志檔案的相對偏移量在index索引檔案不存在,可根據其在index索引檔案最接近的上限偏移量,往下順序查找。
segment index file采取稀疏索引存儲方式,即<偏移量、位置>,它減少索引檔案大小,通過map可以直接記憶體操作,稀疏索引為資料檔案的每個對應message設定一個中繼資料指針,它比稠密索引節省了更多的存儲空間,但查找起來需要消耗更多的時間。
總結
- topic是邏輯概念,partition是實體概念
- .log檔案存放實際資料,生産者的資料都會追加到.log檔案中
- 為防止.log檔案過大導緻資料定位效率低下,kafka采取了分片和索引機制,将partition分為多個segment,分别進行索引
- .index檔案存儲大量的索引資訊,.log檔案存儲大量的資料,索引檔案中的中繼資料指向對應資料檔案中Message的實體偏移位址。
參考連結:https://blog.csdn.net/moshang_3377/article/details/103436537