每個topic,分爲多個partition,每個partition在文件系統當中是一個文件夾。java
而每個partition當中,又分紅了多個segment,每一個segment,包括了2個文件,.index文件和.log文件,分別是消息的索引信息和消息內容。而文件的名字形以下面的格式異步
00000000000000000000.logsocket
00000000000000000000.index線程
0000000000000999.log設計
0000000000000999.index索引
文件名的就是消息在本分區當中的序號,以上面的文件爲例,第一個segment當中存儲了0-999的消息,而第二個segment從1000開始。內存
須要注意的是segment的劃分規則,目前據個人研究,是綜合了2方面的因素,一個是設定的segment的大小,滿了天然會再來一個segment;第二個因素是時間的因素,好比某個topic長時間沒有消息寫入,那麼在有新消息進來的時候,極可能會從新建一個segment,這樣作的目的是爲了方便在消息失效的時候,針對整個segment進行刪除。it
index文件當中,包含了2部份內容,分別是消息的在本segment當中的編號和物理offset。這裏須要注意的是,在index文件當中,並非存儲了每一條消息的的索引信息,而是採用了 稀疏索引的策略,也就是隔幾個存一個索引。io
在查找一條消息的時候,首先是根據segment的名字和輸入的消息編號,查找所在的segment,以後在根據index文件找到消息的具體位置。file
寫過程:
消息從java堆轉入page cache(即物理內存)
由異步線程刷盤,消息從page cache刷入磁盤
讀過程:
消息直接從page cache轉入socket發送出去
當從page cache沒有找到相應數據時,此時會產生磁盤IO,從磁 盤Load消息到page cache,而後直接從socket發出去
存儲設計的優勢:
Kafka把topic中一個parition大文件分紅多個小文件段,經過多個小文件段,就容易按期清除或刪除已經消費完文件,減小磁盤佔用。
經過索引信息能夠快速定位message
經過index元數據所有映射到memory,能夠避免segment file的IO磁盤操做
經過索引文件稀疏存儲,能夠大幅下降index文件元數據佔用空間大小