Kafka数据存储详解
1.存儲格式概述
?
-
每一個partion(文件夾)相當于一個巨型文件被平均分配到多個大小相等segment(段)數(shù)據(jù)文件里。但每一個段segment file消息數(shù)量不一定相等,這樣的特性方便old segment fifile高速被刪除。(默認情況下每一個文件大小為1G)
-
每一個partiton僅僅須要支持順序讀寫即可了。segment文件生命周期由服務(wù)端配置參數(shù)決定。
partiton中segment文件存儲結(jié)構(gòu)
segment fifile組成:由2大部分組成。分別為index file和data file,此2個文件一一相應(yīng),成對出現(xiàn),后綴”.index”和“.log”分別表示為segment索引文件、數(shù)據(jù)文件.
segment文件命名規(guī)則:partion全局的第一個segment從0開始,之后每一個segment文件名稱為上一個segment文件最后一條消息的offset值。數(shù)值最大為64位long大小。19位數(shù)字字符長度,沒有數(shù)字用0填充。
[root@VM_0_7_centos yfy-0]# ll total 4 -rw-r--r-- 1 root root 10485760 Oct 13 19:37 00000000000000000000.index -rw-r--r-- 1 root root ? ? ? ?0 Oct 13 19:37 00000000000000000000.log -rw-r--r-- 1 root root 10485756 Oct 13 19:37 00000000000000000000.timeindex -rw-r--r-- 1 root root ? ? ? ?8 Oct 13 19:37 leader-epoch-checkpoint2.日志索引
2.1 數(shù)據(jù)文件的分段
數(shù)據(jù)文件以該段中最小的offset命名。這樣在查找指定offset的Message的時候,用二分查找就可以定位到該Message在哪個段中。
2.2 偏移量索引
數(shù)據(jù)文件分段使得可以在一個較小的數(shù)據(jù)文件中查找對應(yīng)offffset的Message了,但是這依然需要順序掃描才能找到對應(yīng)offset的Message。為了進一步提高查找的效率,Kafka為每個分段后的數(shù)據(jù)文件建立了索引文件,文件名與數(shù)據(jù)文件的名字是一樣的,只是文件擴展名為.index。
?
比如:要查找絕對offffset為7的Message:
首先是用二分查找確定它是在哪個LogSegment中,自然是在第一個Segment中。 打開這個Segment的index文件,也是用二分查找找到offffset小于或者等于指定offffset的索引條目中最大的那個offset。自然offset為6的那個索引是我們要找的,通過索引文件我們知道offffset為6的Message在數(shù)據(jù)文件中的位置為9807。
打開數(shù)據(jù)文件,從位置為9807的那個地方開始順序掃描直到找到offset為7的那條Message。
這套機制是建立在offset是有序的。索引文件被映射到內(nèi)存中,所以查找的速度還是很快的。
一句話,Kafka的Message存儲采用了分區(qū)(partition),分段(LogSegment)和稀疏索引這幾個手段來達到了高效性。
3.日志刪除
Kafka日志管理器允許定制刪除策略。目前的策略是刪除修改時間在N天之前的日志(按時間刪除),也可以使用另外一個策略:保留最后的N GB數(shù)據(jù)的策略(按大小刪除)。為了避免在刪除時阻塞讀操作,采用了copy-on-write形式的實現(xiàn),刪除操作進行時,讀取操作的二分查找功能實際是在一個靜態(tài)的快照副本上進行的,這類似于Java的CopyOnWriteArrayList。
Kafka消費日志刪除思想:Kafka把topic中一個parition大文件分成多個小文件段,通過多個小文件段,就容易定期清除或刪除已經(jīng)消費完文件,減少磁盤占用。
# 清理超過指定時間清理: log.retention.hours=16 # 超過指定大小后,刪除舊的消息: log.retention.bytes=10737418244.磁盤存儲優(yōu)勢
Kafka在設(shè)計的時候,采用了文件追加的方式來寫入消息,即只能在日志文件的尾部追加新的消息,并且不允許修改已經(jīng)寫入的消息,這種方式屬于典型的順序?qū)懭氪伺袛嗟牟僮?#xff0c;所以就算是Kafka使用磁盤作為存儲介質(zhì),所能實現(xiàn)的額吞吐量也非常可觀。
Kafka中大量使用頁緩存,這也是Kafka實現(xiàn)高吞吐的重要因素之一。
頁緩存可以看下面這兩篇博客:
-
聊聊page cache與Kafka之間的事兒:https://www.jianshu.com/p/92f33aa0ff52
-
linux中的頁緩存和文件IO:https://blog.csdn.net/gdj0001/article/details/80136364
?
Kafka中讀寫message有如下特點:
寫message
-
消息從java堆轉(zhuǎn)入page cache(即物理內(nèi)存)。
-
由異步線程刷盤,消息從page cache刷入磁盤。
讀message
-
消息直接從page cache轉(zhuǎn)入socket發(fā)送出去。
-
當從page cache沒有找到相應(yīng)數(shù)據(jù)時,此時會產(chǎn)生磁盤IO,從磁盤Load消息到page cache,然后直接從socket發(fā)出去
Kafka高效文件存儲設(shè)計特點
-
Kafka把topic中一個parition大文件分成多個小文件段,通過多個小文件段,就容易定期清除或刪除已經(jīng)消費完文件,減少磁盤占用。
-
通過索引信息可以快速定位message和確定response的最大大小。
-
通過index元數(shù)據(jù)全部映射到memory,可以避免segment file的IO磁盤操作。
-
通過索引文件稀疏存儲,可以大幅降低index文件元數(shù)據(jù)占用空間大小。
總結(jié)
以上是生活随笔為你收集整理的Kafka数据存储详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: git的一些常用命令讲解和开发规范总结
- 下一篇: kafka消费组与重平衡机制详解