Kafka中的消息以Topic進行分類,生產者與消費者都是面向Topic處理數據。 Topic是邏輯上的概念,而Partition是物理上的概念,每一個Partition分爲多個Segment,每一個Segment對應兩個文件,一個索引文件,一個日誌文件。Producer生產的數據會被不斷的追加到日誌文件的末端,且每條數據都有本身的offset。消費組中的每一個Consumer都會實時記錄本身消費到了哪一個offset,以便出錯恢復時,從上次的位置繼續消費。html
因爲Producer產生的消息會不斷的追加到日誌文件的末尾,這樣將對消息文件的維護以及以消費的消息的清理帶來嚴重的影響,所以,Kafka引入的分片和索引的設計。每一個Partition對應一個文件夾;「topic名稱 分區序號」。每一個Partition分爲多個Segment,Segment分爲兩類文件:「.index」索引文件與「.log」數據文件,其中索引文件和數據文件都在Partition對應的文件夾中。 假設test-topic有3個分區,則對應的文件夾名稱爲:test-topic-0、test-topic-一、test-topic-2。 partition文件夾下文件形如:git
00000000000000000000.index 00000000000000000000.log 00000000000000170410.index 00000000000000170410.log 00000000000000239430.index 00000000000000239430.log
能夠看到有索引文件與數據文件,有3個Segment。 這兩個文件的命令規則爲:Partition全局的第一個Segment從0開始,後續每一個Segment文件名爲上一個Segment文件最後一條消息的offset值,數值大小爲64位,20位數字字符長度,沒有數字用0填充。分佈式
以Segment文件的詳細內容: 圖中,索引文件存儲的元數據指向數據文件中的message的物理偏移地址。設計
以上圖爲例,讀取offset=170418的消息,首先查找segment文件,其中00000000000000000000.index 爲最開始的文件,第二個文件爲 00000000000000170410.index(起始偏移爲 170410 1=170411),而第三個文件爲 00000000000000239430.index(起始偏移爲 239430 1=239431),因此這個 offset=170418 就落到了第二個文件之中。其它後續文件能夠依次類推,以其偏移量命名並排列這些文件,而後根據二分查找法就能夠快速定位到具體文件位置。其次根據 00000000000000170410.index 文件中的 [8,1325] 定位到 00000000000000170410.log 文件中的 1325 的位置進行讀取。要是讀取 offset=170418 的消息,從 00000000000000170410.log 文件中的 1325的位置進行讀取,那麼,如何肯定什麼時候讀完本條消息呢? 這個問題由消息的物理結構解決,消息都具備固定的物理結構,包括:offset(8 Bytes)、消息體的大小(4 Bytes)、crc32(4 Bytes)、magic(1 Byte)、attributes(1 Byte)、key length(4 Bytes)、key(K Bytes)、payload(N Bytes)等等字段,能夠肯定一條消息的大小,即讀取到哪裏截止。日誌