Kafka工作流程及文件存儲(chǔ)機(jī)制
點(diǎn)擊上方藍(lán)色字體,選擇“設(shè)為星標(biāo)”
回復(fù)”資源“獲取更多資源

文章目錄
一,Kafka工作流程
二,文件存儲(chǔ)機(jī)制
2.1 存儲(chǔ)機(jī)制
2.2 index和log文件詳解
2.3 message的結(jié)構(gòu)
2.4 如何通過offset查找Message?
三,數(shù)據(jù)目錄結(jié)構(gòu)

Kafka中消息是以topic進(jìn)行分類的,生產(chǎn)者生產(chǎn)消息,消費(fèi)者消費(fèi)消息,都是面向topic的。
topic是邏輯上的概念,而partition是物理上的概念,每個(gè)partition對(duì)應(yīng)于一個(gè)log文件,該log文件中存儲(chǔ)的就是producer生產(chǎn)的數(shù)據(jù)。Producer生產(chǎn)的數(shù)據(jù)會(huì)被不斷追加到該log文件末端,且每條數(shù)據(jù)都有自己的offset。
offset是一個(gè)long型的數(shù)字,我們通過這個(gè)offset可以確定一條在該partition下的唯一消息。在partition下面是保證了有序性,但是在topic下面沒有保證有序性。
消費(fèi)者組中的每個(gè)消費(fèi)者,都會(huì)實(shí)時(shí)記錄自己消費(fèi)到了哪個(gè)offset ,以便出錯(cuò)恢復(fù)時(shí),從上次的位置繼續(xù)消費(fèi)。
二,文件存儲(chǔ)機(jī)制
2.1 存儲(chǔ)機(jī)制


由于生產(chǎn)者生產(chǎn)的消息會(huì)不斷追加到log文件末尾,為防止log文件過大導(dǎo)致數(shù)據(jù)定位效率低下,Kafka采取了分片和索引機(jī)制,將每個(gè)partition分為多個(gè)segment(邏輯概念,等于index+log文件)。
每個(gè)partition(目錄)相當(dāng)于一個(gè)巨型文件被平均分配到多個(gè)大小相等的segment(片段)數(shù)據(jù)文件中(每個(gè)segment文件中消息數(shù)量不一定相等),這種特性也方便old segment的刪除,即方便已被消費(fèi)的消息的清理,提高磁盤的利用率。每個(gè)partition只需要支持順序讀寫就行,segment的文件生命周期由服務(wù)端配置參數(shù)(log.segment.bytes,log.roll.{ms,hours}等若干參數(shù))決定。
每個(gè)segment對(duì)應(yīng)兩個(gè)文件——“.index”文件和“.log”文件。分別表示為segment索引文件和數(shù)據(jù)文件(引入索引文件的目的就是便于利用二分查找快速定位message位置)。這兩個(gè)文件的命令規(guī)則為:partition全局的第一個(gè)segment從0開始,后續(xù)每個(gè)segment文件名以當(dāng)前segment的第一條消息的offset命名,數(shù)值大小為64位,20位數(shù)字字符長度,沒有數(shù)字用0填充。
這些文件位于一個(gè)文件夾下(partition目錄),該文件夾的命名規(guī)則為:topic名稱+分區(qū)序號(hào)。例如,first這個(gè)topic有三個(gè)分區(qū),則其對(duì)應(yīng)的文件夾為first-0,first-1,first-2。
00000000000000000000.index00000000000000000000.log00000000000000170410.index00000000000000170410.log00000000000000239430.index00000000000000239430.log[root@cm1 data]# pwd/var/local/kafka/data[root@cm1 data]# tree.├── cleaner-offset-checkpoint├── meta.properties├── recovery-point-offset-checkpoint├── replication-offset-checkpoint# partition目錄(topic名稱+分區(qū)序號(hào))├── test-0# segment索引文件│ ├── 00000000000000000000.index# 數(shù)據(jù)文件│ ├── 00000000000000000000.log# 0.8版本之前的kafka沒有timeindex文件,這是kafka的具體時(shí)間日志│ └── 00000000000000000000.timeindex│ ├── 00000000000000170410.index│ ├── 00000000000000170410.log│ └── 00000000000000170410.timeindex├── test-1│ ├── 00000000000000000000.index│ ├── 00000000000000000000.log│ └── 00000000000000000000.timeindex└── test-2├── 00000000000000000000.index├── 00000000000000000000.log????└──?00000000000000000000.timeindex
index和log文件以當(dāng)前segment的第一條消息的offset命名。下圖為index文件和log文件的結(jié)構(gòu)示意圖。

2.2 index和log文件詳解
.index索引文件存儲(chǔ)大量的索引信息,.log數(shù)據(jù)文件存儲(chǔ)大量消息數(shù)據(jù)(Message),索引文件中的元數(shù)據(jù)指向?qū)?yīng)數(shù)據(jù)文件中Message的物理偏移地址。以index索引文件中的元數(shù)據(jù)3,497為例,依次在數(shù)據(jù)文件中表示第三個(gè)Message(在全局Partition中表示第368772個(gè)message),以及該消息的物理偏移地址為497.
索引和日志文件內(nèi)部的關(guān)系,如圖:

2.3 message的結(jié)構(gòu)
Segment的Log文件由多個(gè)Message組成,下面詳細(xì)說明Message的物理結(jié)構(gòu),如圖:

參數(shù)說明:

2.4 如何通過offset查找Message?
先二分查找獲取對(duì)應(yīng)index索引文件,獲取到對(duì)應(yīng)的物理offset
拿著物理offset去log數(shù)據(jù)文件順序查找對(duì)應(yīng)消息
返回查找到的消息
例如,讀取offset=368776的Message,需要通過如下兩個(gè)步驟。
第一步:查找Segment File.
00000000000000000000.index表示最開始的文件,起始偏移量(offset)為0;第二個(gè)文件00000000000000368770.index的起始偏移量為368770,依次類推。以起始偏移量命名并排序這些文件,只要根據(jù)offset二分查找文件列表,就可以快速定位到具體文件。
當(dāng)offset=368776時(shí),定位到00000000000000368770.index|log。
第二步:通過Segment File 查找Message。
通過第一步定位到Segment File,當(dāng)offset=368776時(shí),依次定位到00000000000000368770.index的元數(shù)據(jù)物理位置和00000000000000368770.log的物理偏移地址,然后再通過00000000000000368770.log順序查找,直到offset=368776為止。
Segment Index File采取稀疏索引存儲(chǔ)方式,可以減少索引文件大小,通過Linux mmap接口可以直接進(jìn)行內(nèi)存操作。稀疏索引為數(shù)據(jù)文件的每個(gè)對(duì)應(yīng)Message設(shè)置一個(gè)元數(shù)據(jù)指針,它比稠密索引節(jié)省了更多的存儲(chǔ)空間,但查找起來需要消耗更多的時(shí)間。
三,數(shù)據(jù)目錄結(jié)構(gòu)
舉例說明,向主題topic-log中發(fā)送一定量的消息,某一時(shí)刻topic-log-0目錄中的布局如下所示。

示例中第2個(gè)LogSegment對(duì)應(yīng)的基準(zhǔn)位移是133,也說明了該LogSegment中的第一條消息的偏移量為133,同時(shí)可以反映出第一個(gè)LogSegment中共有133條消息(偏移量從0至132的消息)。
注意每個(gè)LogSegment中不只包含“.log”“.index”“.timeindex”這3種文件,還可能包含 “.deleted”“.cleaned”“.swap”等臨時(shí)文件,以及可能的“.snapshot”“.txnindex”“l(fā)eader-epoch-checkpoint”等文件。
從更加宏觀的視角上看,Kafka 中的文件不只上面提及的這些文件,比如還有一些檢查點(diǎn)文件,當(dāng)一個(gè)Kafka服務(wù)第一次啟動(dòng)的時(shí)候,默認(rèn)的根目錄下就會(huì)創(chuàng)建以下5個(gè)文件:
├── cleaner-offset-checkpoint├── meta.properties├── recovery-point-offset-checkpoint├── replication-offset-checkpoint├──?log-start-offset-checkpoint
kafka0.8之后消費(fèi)者提交的位移是保存在 Kafka 內(nèi)部的主題__consumer_offsets中的,初始情況下這個(gè)主題并不存在,當(dāng)?shù)谝淮斡邢M(fèi)者消費(fèi)消息時(shí)會(huì)自動(dòng)創(chuàng)建這個(gè)主題。
在某一時(shí)刻,Kafka 中的文件目錄布局如圖 所示。每一個(gè)根目錄都會(huì)包含最基本的 4個(gè)檢查點(diǎn)文件(xxx-checkpoint)和 meta.properties 文件。在創(chuàng)建主題的時(shí)候,如果當(dāng)前 broker中不止配置了一個(gè)根目錄,那么會(huì)挑選分區(qū)數(shù)最少的那個(gè)根目錄來完成本次創(chuàng)建任務(wù)。

文章不錯(cuò)?點(diǎn)個(gè)【在看】吧!??


