1、Kafka部分名詞解釋
在一套 Kafka 架構中有多個 Producer,多個 Broker,多個 Consumer,每個 Producer 可以對應多個 Topic,每個 Consumer 只能對應一個 Consumer Group,
整個 Kafka 架構對應一個 ZK 集群,通過 ZK 管理集群配置,選舉 Leader,以及在 Consumer Group 發生變化時進行 Rebalance,

- Broker:訊息中間件處理結點,一個Kafka節點就是一個broker,多個broker可以組成一個Kafka集群,
- Topic:一類訊息,例如page view日志、click日志等都可以以topic的形式存在,Kafka集群能夠同時負責多個topic的分發,
- Partition:topic物理上的分組,一個topic可以分為多個partition,每個partition是一個有序的佇列,
- Segment:partition物理上由多個segment組成,
2、分析程序
- topic中partition存盤分布
- partiton中檔案存盤方式
- partiton中segment檔案存盤結構
- 在partition中如何通過offset查找message
3、topic中partition存盤分布
只有一個broker的情況
假設實驗環境中kafka集群只有一個broker,xxx/message-folder為資料檔案存盤根目錄,在Kafka的broker中server.properties檔案配置(引數log.dirs=xxx/message-folder),例如創建2個topic名 稱分別為info_add、info_update, partitions數量都為partitions=4,
存盤路徑和目錄規則為:
|–info_add-0
|–info_add-1
|–info_add-2
|–info_add-3
|–info_update-0
|–info_update-1
|–info_update-2
|–info_update-3
在Kafka檔案存盤中,同一個topic下有多個不同partition,每個partition為一個目錄,partiton命名規則為topic名稱+有序序號,第一個partiton序號從0開始,序號最大值為partitions數量減1,
多broker分布的情況
Kafka集群partition replication,默認自動分配
(1)下面以一個Kafka集群中4個Broker舉例,創建1個topic包含4個Partition,2 Replication;資料Producer流動如圖所示:

(2)當集群中新增2個節點,Partition增加到6個節點時的分布情況如下:

副本分配邏輯規則
在Kafka集群中,每個Broker都有均等分配Partition的Leader機會,
上述圖中的Broker Partition中,箭頭指向為副本,以Partition-0為例:broker1中parition-0為Leader,Broker2中Partition-0為副本,
上述圖中每個Broker(按照BrokerId有序)依次分配主Partition,下一個Broker為副本,如此回圈迭代分配,多副本都遵循此規則,
副本分配演算法
將所有N個Broker和待分配的i個Partition排序,
將第i個Partition分配到第(i mod n)個Broker上,
將第i個Partition的第j個副本分配到第((i + j) mod n)個Broker上,
4、partiton中檔案存盤方式
下面示意圖形象說明了partition中檔案存盤方式:

每個partion(目錄)相當于一個巨型檔案被平均分配到多個大小相等segment(段)資料檔案中,但每個段segment file訊息數量不一定相等,這種特性方便old segment file快速被洗掉,
每個partiton只需要支持順序讀寫就行了,segment檔案生命周期由服務端配置引數決定,
這樣做的好處就是能快速洗掉無用檔案,有效提高磁盤利用率,
5、partition中segment檔案存盤結構
下面深入分析partition中segment file組成和物理結構,
segment file組成:由2大部分組成,分別為index file和data file,此2個檔案一一對應,成對出現,后綴".index"和“.log”分別表示為segment索引檔案、資料檔案,
segment檔案命名規則:partion全域的第一個segment從0開始,后續每個segment檔案名為上一個全域partition的最大offset(偏移message數),數值最大為64位long大小,19位數字字符長度,沒有數字用0填充,
在Kafka broker上做一個實驗,創建一個topicXXX包含1 partition,設定每個segment大小為500MB,并啟動producer向Kafka broker寫入大量資料,如下圖所示的segment檔案串列正好形象說明了上述2個規則:

以上述圖中的一對segment file檔案為例,說明segment中index<—->data file對應關系物理結構如下:

上述圖中的索引檔案存盤大量元資料,資料檔案存盤大量訊息,索引檔案中元資料指向對應資料檔案中message的物理偏移地址,其中以索引檔案中元資料3,497為例,依次在資料檔案中表示第3個message(在全域partiton表示第368772個message)、以及該訊息的物理偏移地址為497,
segment data file由許多message組成,下面詳細說明message物理結構:

引數說明:

6、在partition中如何通過offset查找message
例如讀取offset=368776的message,需要通過下面2個步驟查找,
(1)查找segment file
00000000000000000000.index表示最開始的檔案,起始偏移量(offset)為0,第二個檔案00000000000000368769.index的訊息量起始偏移量為368770 = 368769 + 1,同樣,第三個檔案00000000000000737337.index的起始偏移量為737338=737337 + 1,其他后續檔案依次類推,以起始偏移量命名并排序這些檔案,只要根據offset 二分查找檔案串列,就可以快速定位到具體檔案,
當offset=368776時定位到00000000000000368769.index|log,
(2)通過segment file 查找message
通過第(1)步定位到segment flie,當offset=368776時,依次定位到00000000000000368769.index的元資料物理位置和 00000000000000368769.log的物理偏移地址,然后再通過00000000000000368769.log順序查找直到 offset=368776為止,
這樣做的優點,segment index file采取稀疏索引存盤方式,它減少索引檔案大小,通過mmap可以直接記憶體操作,稀疏索引為資料檔案的每個對應message設定一個元資料指標,它比稠密索引節省了更多的存盤空間,但查找起來需要消耗更多的時間,
7、Kafka服務端配置及其優化
每個kafka broker中組態檔server.properties默認必須配置的屬性如下:
broker.id=0
num.network.threads=2
num.io.threads=8
socket.send.buffer.bytes=1048576
socket.receive.buffer.bytes=1048576
socket.request.max.bytes=104857600
log.dirs=/tmp/kafka-logs
num.partitions=2
log.retention.hours=168
log.segment.bytes=536870912
log.retention.check.interval.ms=60000
log.cleaner.enable=false
zookeeper.connect=localhost:2181
zookeeper.connection.timeout.ms=1000000
server.properties中所有配置引數說明(解釋)如下串列:

8、Kafka檔案存盤機制–實際運行效果
實驗環境:
Kafka集群:由2臺虛擬機組成
cpu:4核
物理記憶體:8GB
網卡:千兆網卡
jvm heap: 4GB

從上述圖中可以看出基本沒有大量讀磁盤的操作,只有(定期批量)寫磁盤操作,之所以操作磁盤這么高效,這跟Kafka檔案存盤設計中讀寫message是息息相關的,
Kafka中讀寫message有如下特點:
寫message
(1)訊息從java堆轉入Page Cache(即物理記憶體),
(2)由異步執行緒刷盤,訊息從pagacache刷入磁盤,
讀message
(1)訊息直接從Page Cache(資料在虛擬記憶體)轉入socket發送出去,
(2)當從Page Cache沒有找到相應資料時,此時會產生磁盤IO,從磁盤Load訊息到Page Cache,然后直接從socket發出去,
9、總結
Kafka高效檔案存盤設計特點
(1)Kafka把topic中一個parition大檔案分成多個小檔案段,通過多個小檔案段,就容易定期清除或洗掉已經消費完檔案,減少磁盤占用,
(2)通過索引資訊可以快速定位message和確定response的最大大小,
(3)通過index元資料全部映射到memory,可以避免segment file的IO磁盤操作,
(4)通過索引檔案稀疏存盤,可以大幅降低index檔案元資料占用空間大小,
參考:
https://www.open-open.com/lib/view/open1421150566328.html
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/246150.html
標籤:其他
