kafka connect 數據寫hdfs詳解

曾經有位學者說過,“read the F**K code”。不多說,從TopicPartitionWriter的write方法中可以得到如下狀態機:

Created with Raphaël 2.1.0WRITE_STARTEDWRITE_PARTITION_PAUSEDshouldRotate()SHOULD_ROTATETEMP_FILE_CLOSEDFILE_COMMITTEDyesno

1. 狀態機中各狀態說明

WRITE_STARTED

初始狀態,無條件進入下一狀態

WRITE_PARTITION_PAUSED

如果緩衝區中有數據,將緩衝區中數據寫入hdfs tmp文件。

SHOULD_ROTATE

關閉hdfs tmp文件。

TEMP_FILE_CLOSED

數據到目標文件的準備工作,寫WAL。

WAL_APPENDED

將TMP文件轉化爲目標文件。

FILE_COMMITTED

無條件跳轉到 WRITE_PARTITION_PAUSED狀態。

2. 狀態機中條件說明

shouldRotate()

滿足兩個條件中任意一個就開始寫:
1. 時間到,可配置,例如15分鐘/60分鐘寫入一次等(非定時器實現);
2. 讀取的record數量達到配置值;
代碼詳見,下類的shouldRotate方法:

kafka-connect-hdfs-2.0.0\src\main\java\io\confluent\connect\hdfs\TopicPartitionWriter.java

3 . 附加說明

1. TMP文件

每次kafka connector從kafka中poll數據後,先將數據寫往hdfs的tmp目錄。
1. 線程爲每個kafka分區分配一個tmp文件;
2. 文件放在/topic/+tmp/分區/目錄下;
3. 文件名爲隨機產生的UUID_tmp.parquet;
4. 不是每條記錄都會直接和hdfs交互,parquet有內存緩存,寫hdfs時機可以參見:

\org\apache\parquet\hadoop\InternalParquetRecordWriter.java

2. WAL

全名”Write Ahead Log”,當異常發生時,可基於日誌進行恢復,恢復過程詳細下類的recover方法:

kafka-connect-hdfs-2.0.0\src\main\java\io\confluent\connect\hdfs\TopicPartitionWriter.java

3. 寫入目標文件

從Tmp目錄到目標目錄不會發生大規模的IO,只是做了hdfs文件的重命名,詳見下類中的commit方法

kafka-connect-hdfs-2.0.0\src\main\java\io\confluent\connect\hdfs\storage\HdfsStorage.java

4. 目標文件的隱藏地圖

目標文件的命名實際很講究,看

 /topics/topic名稱/ hive分區列和值/ kafka分區+開始offset+結束offset

暗藏恢復處理流程:當新的thread接管分區的處理,或者thread從異常中恢復。會先根據該分區下最後寫入的文件名獲取最後的offset。
Kafka connect commit offset是不按套路出牌的,讀了數據有個記錄,然後定時commit。Image這種情況:數據已經寫入了目標文件,但是還沒有commit,那再讀的時候,就會重複讀數據。如果知道寫入hdfs最後的offset就不一樣了,重複的數據直接忽略掉。具體過程請參考下類的resetOffsets方法。

kafka-connect-hdfs-2.0.0\src\main\java\io\confluent\connect\hdfs\TopicPartitionWriter.java
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章