Spark + Kafka 整合 指南
阿新 • • 發佈:2019-01-08
最近在考慮Spark在消費Kafka 分割槽資料的過程中究竟反生了什麼? 因為比較疑惑現有系統架構會不會遭遇這方面的瓶頸,遂決定去搞一把,一探究竟.
關於Kafka做一下簡短的總結,Kafka可參考附件1:
- 多個TOPIC分佈在多個Broker中
- 每個TOPIC的資料以分割槽的方式分佈在多個Broker中
- 一個分割槽同時只能被一個Consumer消費
- 同一個TOPIC允許被不同的Group重複消費,Group內不允許重複消費
Spark接入Kafka資料的兩種方式Receiver-based && Direct Approach. 各有特點.
Receiver-based,基於接收器的kafka資料消費,
- API示例如下
val kafkaStream = KafkaUtils.createStream(streamingContext, [ZK quorum], [consumer group id], [per-topic number of Kafka partitions to consume])
- 概述
- KAFKA高階API實現,因而程式設計實現簡單.
- 接收器接負責收資料儲存到Sparnk 執行器,可能是記憶體或者磁碟
- 預設配置下潛在的資料丟失風險,可以啟用客戶端日誌特性,該操作將對消費的資料進行以日誌檔案形式進行儲存進而避免依賴於ZK的資料消費異常
- 點晴
- 基於接收器的Kafka資料消費Kafka分割槽與RDD分割槽之間沒有關聯,進而引數[per-topic number of Kafka partitions to consume] ,實際上只是增加了接收器接收資料的並行度而並沒有提高Saprk 處理資料的並行度.
- 可以使用多個Reciver來並行消費不同Topic 及不同Group下的資料
- 啟用日誌特性需要指定資料的儲存級別,KafkaUtils.createStream(..., StorageLevel.MEMORY_AND_DISK_SER)
- 基於接收器的Kafka資料消費Kafka分割槽與RDD分割槽之間沒有關聯,進而引數[per-topic number of Kafka partitions to consume] ,實際上只是增加了接收器接收資料的並行度而並沒有提高Saprk 處理資料的並行度.
Direct Approach,直接獲取資料
- 概述
- 一種端對端的資料消費策略,一個Kafka分割槽對應一個RDD分割槽.
- 定期的快速掃描Kafka中每個Partion 及Topic 的最新Offsets以確定當前批次的資料偏移範圍,該過程使用低階API來實現
- 優勢
- 簡化的並行度,基於DirectStream SparkStream將建立多個RDD分割槽去消費Kafka分割槽資料
- 效率上的提升,客戶端Offsets不再依賴於ZK儲存的Offsets而改由Spark checkPoint 進行跟蹤,每次取資料直接使用偏移獲取
- 一次消費保證, Offsets 不在依賴於ZK ,排除了ZK Offsets可能不同步的情況,消除了 Spark和Kafka之間的不一致性,意味著資料的消費由Spark掌控,只要資料存在於Kafka即可.
- 簡化的並行度,基於DirectStream SparkStream將建立多個RDD分割槽去消費Kafka分割槽資料
- 弊端
- offsets由Spark在checkpoint中維護不自動更新ZK中的Offsets,導致一些依賴於ZKOffsets監控的工具失效.
- 配置專案
- auto.offset.reset 消費者首次連線時offsets的生成策略,largest/smallest,分別代表當前最新訊息位置/最早訊息位置.
- spark.streaming.kafka.* 其它可配置的引數
- spark.streaming.kafka.maxRetries 最大重試次數
- spark.streaming.kafka.maxRatePerPartition 每秒中消費的最大條數 ,該引數對於從資料積壓中進行恢復有顯著調節作用.
附件1:kafka 知識圖解