Druid中的Kafka Indexing Service源碼分析

Kafka Indexing Service開發的目的是爲了增強Kafka中數據的實時攝入。其特性如下:

  • 保障數據攝入的Exactly Once。
  • 可以攝入任意時間戳的數據,而不僅僅是當前數據。
  • 可以根據Kafka分區的變化二調整任務的數量。

影響數據攝入Exactly Once的主要因素是Kafka的Offset管理。Kafka Indexing Service爲了實現Exactly Once語義,去掉了windowPeriod,並採用底層API實現了對Offset的事務管理。

Kafka Indexing Service的類圖如下:


其中:

KafkaSupervisor

負責整個Kafka Indexing Service的創建以及其整個生命週期的管理,它監管Kafka Indexing Service的狀態來完成協調移交,管理失敗,同時保障添加/刪除Kafka 分區以後的可擴展性以及任務的多副本執行。

TaskGroups

是KafkaSupervisor管理partition,Offset和Indexing service的數據結構,用來保障任務的多副本執行。每個TaskGroups中的所有任務做的都是相同的事情。讀取分配給TaskGroups的所有partition的數據,而且都是從相同的Offset開始讀取。通過修改replicas的值來調整任務副本數量。

KafkaPartitions
用來記錄Kafka的Topic以及Partition -> Offset關係映射。

KafkaIndexTask

從KafkaIOConfig的startPosition中的offset處開始讀取數據,一直到endPartition的結束Offset處結束讀取,發佈移交segment。在執行過程中,startPosition中的Offset不會變,endPosition的Offset初始設置爲: Long.MAX_VALUE。KafkaSupervisor通過修改endPosition的值來結束任務的執行。運行中的任務有兩種狀態:讀取和發佈。任務會保持讀取狀態,直到達到taskDuration以後進入發佈狀態。接下來會保持發佈狀態,直到生成segment,並推送至Deep Storage,然後His節點加載。或者達到completionTimeout的時間。

Appenderator

用來索引數據,採用LSM-Tree結構。這個模塊負責索引和查詢數據,並將Segment推送到Deep Storage中,他只將Segment信息發佈到元數據存儲中。

FiniteAppendratorDriver

驅動Appendrator完成有限流式數據的索引,在索引結束後執行移交操作。它完成Appenderator不能做的那些事情,包括SegmentAllocator將數據分配到指定的Segment,監控移交等。

Kafka Indexing Service利用Kafka的底層Consumer接口,從傳入startOffsets Map{partition, startOffset} 處讀取數據,使用FiniteAppendratorDriver構建Segment。FiniteAppendratorDriver採用有限流失數據的處理方式,讀取固定時間段的數據。

FiniteAppendratorDriver會帶來副作用,會產生一些碎片化的Segment,特別是日誌跨時段亂序延遲嚴重的情況。

如何使用?

將該Extension添加到Overlord和MiddleManager中:

druid.extensions.loadList=["other-modules", "kafka-indexing-service"]

通過 http://<OVERLORD_IP>:<OVERLORD_PORT>/druid/indexer/v1/supervisor 來提交任務。





發佈了45 篇原創文章 · 獲贊 19 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章