Kafka技術知識總結之三——Kafka 高效文件存儲設計

接上篇《Kafka技術知識總結之二——Kafka事務》

三. Kafka 高效文件存儲設計

參考地址:《kafka的消息消費機制、consumer的負載均衡、文件存儲機制》

  1. Kafka 把 topic 中一個 parition 大文件分成多個小文件段,通過多個小文件段,就容易定期清除或刪除已經消費完文件,減少磁盤佔用。
  2. 通過索引信息可以快速定位 message 和確定 response 的最大大小。
  3. 通過 index 元數據全部映射到內存,可以避免 segment 文件的 IO 磁盤操作。
  4. 通過索引文件稀疏存儲,可以大幅降低 index 文件元數據佔用空間大小。

3.1 kafka 文件存儲基本結構

在 Kafka 文件存儲中,同一個 Topic 下有多個不同 partition,每個 partition 爲一個目錄。partition命名規則爲Topic名稱 + 有序序號。如果 partition 數量爲 num,則第一個 partition 序號從 0 開始,序號最大值爲 num - 1。
例如,自己創建一個名爲 orderMq 的 Topic:

[root@mini1 bin]# ./kafka-topics.sh --create --zookeeper mini1:2181 --replication-factor 2 --partitions 3 --topic orderMq
Created topic "orderMq".

orderMq 這個 topic 對應的 partitions 在三臺機器上名稱分別爲:

drwxr-xr-x. 2 root root 4096 11月 21 22:25 orderMq-0
drwxr-xr-x. 2 root root 4096 11月 21 22:25 orderMq-2
drwxr-xr-x. 2 root root 4096 11月 14 18:45 orderMq-1
drwxr-xr-x. 2 root root 4096 11月 14 18:45 orderMq-2
drwxr-xr-x. 2 root root 4096 11月 21 22:25 orderMq-0
drwxr-xr-x. 2 root root 4096 11月 21 22:25 orderMq-1

注:重複的是副本,partition 名分別爲 orderMq-0, orderMq-1, orderMq-2;

每個 partition(即每個目錄)相當於一個巨型文件被平均分配到多個大小相等的 **segment(段)**數據文件中,但每個 segment 消息數量不一定相等。這種特性方便舊 segment 文件快速被刪除,默認保留7天的數據。例如在 orderMq-0 目錄下:

[root@mini3 orderMq-0]# ll
-rw-r--r--. 1 root root 10485760 11月 21 22:31 00000000000000000000.index
-rw-r--r--. 1 root root      219 11月 22 05:22 00000000000000000000.log

由上可知,index 和 log 爲後綴名的文件的合稱,就是 segment 文件。每個 partition 只需要支持順序讀寫就行了,segment 文件生命週期(什麼時候創建,什麼時候刪除)由服務端配置參數決定。

3.2 segment 文件

Segment 文件由兩大部分組成,分別爲索引文件 (index file)數據文件 (data file),這兩個文件一一對應,成對出現。如下圖所示:

Segment 文件列表

Segment 文件命名規則:partition 全局的第一個 segment 從 0 開始,後續每個 segment 文件名爲上一個 segment 文件最後一條消息的 offset 值。數值最大爲 64 位 long 大小,19 位數字字符長度,沒有數字用 0 填充。
索引文件存儲大量元數據,數據文件存儲大量消息。**索引文件中元數據指向對應數據文件中message的物理偏移地址。**如下圖所示:

索引與數據的對應關係

上述圖中 index 文件存儲大量元數據,log 文件存儲大量消息,index 文件中元數據指向對應 log 文件中消息的物理偏移地址。其中以 index 文件中元數據3, 497爲例,依次在數據文件中表示第 3 個消息(當前 Segment 的第 3 個,全局 partition 表示第 368769 + 3 = 368772 個消息),以及該消息在對應 log 文件中的物理偏移地址爲 497。

3.3 kafka 查找消息

讀取 offset=368776 的消息,需要通過下面兩個步驟查找。

  1. 第一步:查找segment file
  • 以起始偏移量命名並排序這些文件,只要根據offset 二分查找文件列表,就可以快速定位到具體文件。
    • 00000000000000000000.index 表示最開始的文件,起始偏移量 (offset) 爲 0
    • 00000000000000368769.index 的消息量起始偏移量爲 368770 = 368769 + 1
    • 00000000000000737337.index 的起始偏移量爲 737338=737337 + 1
  • 其他後續文件依次類推。最後 offset=368776 時定位到 00000000000000368769.index 和對應log文件。
  1. 第二步:通過 Segment 查找消息
    • 當 offset=368776 時,依次定位到 00000000000000368769.index 的元數據物理位置和 00000000000000368769.log 的物理偏移地址,然後再通過 00000000000000368769.log 順序查找直到 offset=368776 爲止。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章