Kafka消息存儲原理

kafka消息存儲機制

(一)關鍵術語java

複習一下幾個基本概念,詳見上面的基礎知識文章。異步

  • Broker:消息中間件處理結點,一個Kafka節點就是一個broker,多個broker可以組成一個Kafka集羣。
  • Topic:一類消息,好比page view日誌、click日誌等都可以以topic的形式存在。Kafka集羣可以同一時候負責多個topic的分發。
  • Partition:topic物理上的分組。一個topic可以分爲多個partition,每個partition是一個有序的隊列。
  • Segment:partition物理上由多個segment組成。如下有具體說明。
  • offset:每個partition都由一系列有序的、不可變的消息組成,這些消息被連續的追加到partition中。partition中的每個消息都有一個連續的序列號叫作offset,用於partition中惟一標識的這條消息。

分析過程分爲如下4個步驟:jvm

  • topic中partition存儲分佈
  • partiton中文件存儲方式
  • partiton中segment文件存儲結構
  • 在partition中怎樣經過offset查找message

經過上述4過程具體分析,咱們就可以清楚認識到kafka文件存儲機制的奧祕。socket

二)topic中partition存儲分佈優化

若是實驗環境中Kafka集羣僅僅有一個broker。xxx/message-folder爲數據文件存儲根文件夾。在Kafka broker中server.properties文件配置(參數log.dirs=xxx/message-folder)。好比建立2個topic名稱分別爲report_push、launch_info, partitions數量都爲partitions=4編碼

存儲路徑和文件夾規則爲:spa

xxx/message-folder線程

|--report_push-0 設計

|--report_push-1 指針

|--report_push-2

|--report_push-3

|--launch_info-0

|--launch_info-1

|--launch_info-2

|--launch_info-3

在Kafka文件存儲中,同一個topic下有多個不一樣partition,每個partition爲一個文件夾,partiton命名規則爲topic名稱+有序序號,第一個partiton序號從0開始,序號最大值爲partitions數量減1。

 

若是是多broker分佈狀況,請參考kafka集羣partition分佈原理分析

(三) partiton中文件存儲方式

如下示意圖形象說明了partition中文件存儲方式:

Alt text

  • 每個partion(文件夾)至關於一個巨型文件被平均分配到多個大小相等segment(段)數據文件裏。但每個段segment file消息數量不必定相等,這樣的特性方便old segment file高速被刪除。(默認狀況下每個文件大小爲1G)
  • 每個partiton僅僅需要支持順序讀寫便可了。segment文件生命週期由服務端配置參數決定。這樣作的優勢就是能高速刪除無用文件。有效提升磁盤利用率。

 

(四) partiton中segment文件存儲結構

讀者從上節瞭解到Kafka文件系統partition存儲方式。本節深刻分析partion中segment file組成和物理結構。

segment file組成:由2大部分組成。分別爲index file和data file,此2個文件一一相應,成對出現,後綴」.index」和「.log」分別表示爲segment索引文件、數據文件.

segment文件命名規則:partion全局的第一個segment從0開始,興許每個segment文件名稱爲上一個segment文件最後一條消息的offset值。

數值最大爲64位long大小。19位數字字符長度,沒有數字用0填充。

如下文件列表是筆者在Kafka broker上作的一個實驗,建立一個topicXXX包括1 partition,設置每個segment大小爲500MB,並啓動producer向Kafka broker寫入大量數據,例如如下圖2所看到的segment文件列表形象說明了上述2個規則:

Alt text

以上述圖2中一對segment file文件爲例。說明segment中index<—->data file相應關係物理結構例如如下:

Alt text

上述圖3中索引文件存儲大量元數據,數據文件存儲大量消息,索引文件裏元數據指向相應數據文件裏message的物理偏移地址。

當中以索引文件裏元數據3,497爲例,依次在數據文件裏表示第3個message(在全局partiton表示第368772個message)、以及該消息的物理偏移地址爲497。

從上述圖3瞭解到segment data file由不少message組成,如下具體說明message物理結構例如如下:

Alt text

keyword 解釋說明 
8 byte offset 在parition(分區)內的每條消息都有一個有序的id號,這個id號被稱爲偏移(offset),它可以惟一肯定每條消息在parition(分區)內的位置。

即offset表示partiion的第多少message 
4 byte message size message大小 
4 byte CRC32 用crc32校驗message 
1 byte 「magic」 表示本次公佈Kafka服務程序協議版本號號 
1 byte 「attributes」 表示爲獨立版本號、或標識壓縮類型、或編碼類型。


4 byte key length 表示key的長度,當key爲-1時,K byte key字段不填 
K byte key 可選 
value bytes payload 表示實際消息數據。

(五)在partition中怎樣經過offset查找message

好比讀取offset=368776的message,需要經過如下2個步驟查找。

  • 第一步查找segment file 
  • 上述圖2爲例。當中00000000000000000000.index表示最開始的文件,起始偏移量(offset)爲0.第二個文件00000000000000368769.index的消息量起始偏移量爲368770 = 368769 + 1.相同,第三個文件00000000000000737337.index的起始偏移量爲737338=737337 + 1。其它興許文件依次類推。以起始偏移量命名並排序這些文件,僅僅要依據offset 二分查找文件列表,就可以高速定位到具體文件。 當offset=368776時定位到00000000000000368769.index|log
  • 第二步經過segment file查找message 
  • 經過第一步定位到segment file,當offset=368776時。依次定位到00000000000000368769.index的元數據物理位置和00000000000000368769.log的物理偏移地址,而後再經過00000000000000368769.log順序查找直到offset=368776爲止。

從上述圖3可知這樣作的優勢,segment index file採取稀疏索引存儲方式,它下降索引文件大小。經過mmap可以直接內存操做,稀疏索引爲數據文件的每個相應message設置一個元數據指針,它比稠密索引節省了不少其它的存儲空間,但查找起來需要消耗不少其它的時間。

(六)Kafka文件存儲機制–實際執行效果

實驗環境:

Kafka集羣:由2臺虛擬機組成

cpu:4核

物理內存:8GB

網卡:千兆網卡

jvm heap: 4GB

具體Kafka服務端配置及其優化請參考:kafka server.properties配置具體解釋

Alt text

從上述圖5可以看出,Kafka執行時很是少有大量讀磁盤的操做。主要是按期批量寫磁盤操做。所以操做磁盤很是高效。

這跟Kafka文件存儲中讀寫message的設計是息息相關的。Kafka中讀寫message有例如如下特色:

寫message

  • 消息從java堆轉入page cache(即物理內存)。
  • 由異步線程刷盤,消息從page cache刷入磁盤。

讀message

  • 消息直接從page cache轉入socket發送出去。
  • 當從page cache沒有找到相應數據時,此時會產生磁盤IO,從磁 
  • 盤Load消息到page cache,而後直接從socket發出去

(七) 總結

  • Kafka高效文件存儲設計特色
  • Kafka把topic中一個parition大文件分紅多個小文件段。經過多個小文件段,就easy按期清除或刪除已經消費完文件。下降磁盤佔用。
  • 經過索引信息可以高速定位message和肯定response的最大大小。
  • 經過index元數據全部映射到memory,可以避免segment file的IO磁盤操做。
  • 經過索引文件稀疏存儲,可以大幅下降index文件元數據佔用空間大小。
相關文章
相關標籤/搜索