kafka 不同分区文件存储_Kafka文件存储机制思考及答案:为什么要分区呢?分区存了哪些内容?...
問題導讀:1、kafka存儲文件結構有哪些?
2、如何理解Partition 分區存在?
3、Segment 存儲是什么?
4、消費者如何通過 offset 查找 message?
一、存儲文件結構
topic:可以理解為一個消息隊列的名字
partition:為了實現擴展性,一個非常大的 topic 可以分布到多個 broker(即服務器)上,一個 topic 可以分為多個 partition,每個 partition 是一個有序的隊列
segment:partition 物理上由多個 segment 組成
message:每個 segment 文件中實際存儲的每一條數據就是 message
offset:每個 partition 都由一系列有序的、不可變的消息組成,這些消息被連續的追加到 partition 中,partition 中的每個消息都有一個連續的序列號叫做 offset,用于 partition 唯一標識一條消息
2020-03-03_164526.jpg (64.35 KB, 下載次數: 2)
2020-3-3 16:35 上傳
二、Partition 分區
本例中 topic 名稱為 test-topic,默認設置 partition 為 3,topic 創建成功后默認的存儲位置在:/tmp/kafka-logs 下,分區分別以 topic 名稱-分區數命名,(不考慮副本的情況)如下:
[mw_shl_code=shell,true]//分布在不同的broker節點上
test-topic-0
test-topic-1
test-topic-2[/mw_shl_code]
疑問一:為什么要分區呢?
為了性能考慮,如果不分區每個 topic 的消息只存在一個 broker 上,那么所有的消費者都是從這個 broker 上消費消息,那么單節點的 broker 成為性能的瓶頸,如果有分區的話生產者發過來的消息分別存儲在各個 broker 不同的 partition 上,這樣消費者可以并行的從不同的 broker 不同的 partition 上讀消息,實現了水平擴展。
疑問二:分區文件下到底存了那些東西?
如下,其實每個分區下保存了很多文件,而概念上我們把他叫segment,即每個分區都是又多個segment構成的,其中 index(索引文件),log(數據文件),time index(時間索引文件)統稱為一個 segment。
[mw_shl_code=shell,true]
test-topic-0
├── 00000000000000000001.index
├── 00000000000000000001.log
├── 00000000000000000001.timeindex
├── 00000000000000001018.index
├── 00000000000000001018.log
├── 00000000000000001018.timeindex
├── 00000000000000002042.index
├── 00000000000000002042.log
├── 00000000000000002042.timeindex[/mw_shl_code]
疑問三: 為什么有了 partition 還需要 segment ?
通過上面目錄顯示存在多個 segment 的情況,既然有分區了還要存多個 segment 干嘛?如果不引入 segment,那么一個 partition 只對應一個文件(log),隨著消息的不斷發送這個文件不斷增大,由于 kafka 的消息不會做更新操作都是順序寫入的,如果做消息清理的時候只能刪除文件的前面部分刪除,不符合 kafka 順序寫入的設計,如果多個 segment 的話那就比較方便了,直接刪除整個文件即可保證了每個 segment 的順序寫入。
三、Segment 存儲
Segment 中核心文件是 index 索引文件和 log 數據文件,既然是索引文件當然是為了更高效的定位到數據,那么索引文件和數據文件中到底是存了那些數據?又是如何快速找到消息數據呢?
3.1 使用 kafka 自帶腳本發送測試數據
[mw_shl_code=shell,true]sh kafka-producer-perf-test.sh --topic test-topic --num-records 50000000 --record-size 1000 --throughput 10000000??--producer-props bootstrap.servers=192.168.60.201:9092[/mw_shl_code]
3.2 使用 kafka 自帶腳本 Dump index
[mw_shl_code=shell,true]sh kafka-run-class.sh kafka.tools.DumpLogSegments --files /tmp/kafka-logs/test-topic-0/00000000000000001018.index --print-data-log
offset: 1049 position: 16205
offset: 1065 position: 32410
offset: 1081 position: 48615
offset: 1097 position: 64820
offset: 1113 position: 81025
offset: 1129 position: 97230[/mw_shl_code]
通過 dump index 我們發現其實索引文件中其實就保存了 offset 和 position,分別是消息的 offset 也就是具體那一條消息,position 表示具體消息存儲在 log 中的物理地址。
疑問一:通過上面數據可以看出,kafka 并不是每個 offset 都保存了,每隔 6 個 offset 存儲一條索引數據,為什么在 index 文件中這些 offset 編號不是連續的呢?
因為 index 文件中并沒有為數據文件中的每條消息都建立索引,而是采用了稀疏存儲的方式,每隔一定字節的數據建立一條索引。這樣避免了索引文件占用過多的空間,從而可以將索引文件保留在內存中。但缺點是沒有建立索引的 Message 也不能一次定位到其在數據文件的位置,從而需要做一次順序掃描,但是這次順序掃描的范圍就很小了。
3.3 使用 kafka 自帶腳本 Dump log
sh kafka-run-class.sh kafka.tools.DumpLogSegments --files /tmp/kafka-logs/test-topic-0/00000000000000001018.log --print-data-log
2020-03-03_164636.jpg (213.42 KB, 下載次數: 2)
2020-3-3 16:36 上傳
log 數據文件中并不是直接存儲數據,而是通過許多的 message 組成,message 包含了實際的消息數據
640.png (80.25 KB, 下載次數: 2)
2020-3-3 16:37 上傳
疑問一:消費者如何通過 offset 查找 message?
假如我們想要讀取 offset=1066 的 message,需要通過下面 2 個步驟查找。
(1)查找 segment file
00000000000000000000.index 表示最開始的文件,起始偏移量 (offset) 為 0.第二個文件 00000000000000001018.index 的消息量起始偏移量為 1019 = 1018 + 1. 同樣,第三個文件 00000000000000002042.index 的起始偏移量為 2043=2042 + 1,其他后續文件依次類推,以起始偏移量命名并排序這些文件,只要根據 offset 二分查找文件列表,就可以快速定位到具體文件。當 offset=1066 時定位到 00000000000000001018.index|log 。
(2)通過 segment file 查找 message
通過第一步定位到 segment file,當 offset=1066時,依次定位到 00000000000000001018.index 的元數據物理位置和 00000000000000001018.log 的物理偏移地址,此時我們只能拿到 1065 的物理偏移地址,然后再通過 00000000000000001018.log 順序查找直到 offset=1066 為止。每個 message 都有固定的格式很容易判斷是否是下一條消息。
2020-03-03_164756.jpg (76.43 KB, 下載次數: 5)
2020-3-3 16:37 上傳
作者:Gent
來源:SegmentFault 社區
最新經典文章,歡迎關注公眾號
總結
以上是生活随笔為你收集整理的kafka 不同分区文件存储_Kafka文件存储机制思考及答案:为什么要分区呢?分区存了哪些内容?...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: apk私钥_使用source/build
- 下一篇: 建模步骤_【设计课堂】游戏手柄建模,看这