整合Kafka兩種模式說明
★面試題:Receiver & Direct
開發中我們經常會利用SparkStreaming實時地讀取kafka中的數據然后進行處理,在spark1.3版本后,kafkaUtils里面提供了兩種創建DStream的方法:
1.Receiver接收方式:
KafkaUtils.createDstream(開發中不用,了解即可,但是面試可能會問)
Receiver作為常駐的Task運行在Executor等待數據,但是一個Receiver效率低,需要開啟多個,再手動合並數據,再進行處理,很麻煩
Receiver那台機器掛了,可能會丟失數據,所以需要開啟WAL(預寫日志)保證數據安全,那么效率又會降低!
Receiver方式是通過zookeeper來連接kafka隊列,調用Kafka高階API,offset存儲在zookeeper,由Receiver維護,
spark在消費的時候為了保證數據不丟也會在Checkpoint中存一份offset,可能會出現數據不一致
所以不管從何種角度來說,Receiver模式都不適合在開發中使用
2.Direct直連方式:
KafkaUtils.createDirectStream(開發中使用,要求掌握)
Direct方式是直接連接kafka分區來獲取數據,從每個分區直接讀取數據大大提高了並行能力
Direct方式調用Kafka低階API,offset自己存儲和維護,默認由Spark維護在checkpoint中,消除了與zk不一致的情況
當然也可以自己手動維護,把offset存在mysql、redis中
所以基於Direct模式可以在開發中使用,且借助Direct模式的特點+手動操作可以保證數據的Exactly once 精准一次
●擴展:關於消息語義
實現方式 |
消息語義 |
存在的問題 |
Receiver |
at most once 最多被處理一次 |
會丟失數據 |
Receiver+WAL |
at least once 最少被處理一次 |
不會丟失數據,但可能會重復消費,且效率低 |
Direct+手動操作 |
exactly once 只被處理一次 |
不會丟失數據,也不會重復消費,且效率高 |
●注意:
開發中SparkStreaming和kafka集成有兩個版本:0.8及0.10+
0.8版本有Receiver和Direct模式(但是0.8版本生產環境問題較多,在Spark2.3之后不支持0.8版本了)
0.10以后只保留了direct模式(Reveiver模式不適合生產環境),並且API有變化(更加強大)
http://spark.apache.org/docs/latest/streaming-kafka-integration.html
●結論:
- 我們學習和開發都直接使用0.10版本中的direct模式
- 但是關於Receiver和Direct的區別面試的時候要能夠答得上來
-Reiⅳver接收模式
- 單個 Receive效率低需要開啟多個 Receiver再手動進行數據合並( union)
- Receiver機器如果掛了,數據會丟失,可以開啟WAL,但是效率又會降低
- Receiver模式使用的是 Kafka的高階封裝的)AP, offset,是維護到zk中,並且 SparkStreaming還會維護到checkpoint中這樣可能會出現數據不一致
- 還有很多其他的問題

Direct直連模式
-
Direct直連模式是直接對接 Kafka的分區讀取效率高
-
使用的是 Kafka的低階(底層的APl, offset是維護到 checkpoint中避免了與zk的不一致當然也可以手動維護到MySQL./ Redis中
注意:
老版本的Kaka本身的 offset!默認在冰k中新版本的在 Kafka的內部主題中 consumer offsets因為zk壓力會很大不適合頻繁更新
♥總結:
不管開發還是學習都直接使用Drec直連模式即可,並且是使用 spark-streaming-kafka010版本
注意:
-
SparkStreaming整合 Kafka有兩個版本的ar包0.8,0.10
-
0.8版本有 Receiⅳer和 Direc模式但是0.8版本生產環境問題較多,在Spak2.3之后不支持0.8版本了)
-
0.10以后只保留了 direct模式( Revelⅳver模式不適合生產環境),並且0.10版本AP有變化(更加強大)