(1) Receiver 方式
使用 kafka 的高層次 API 進行消費,然而,在默認的配置下,這種方式可能會因為底層的失敗而丟失數據。如果要啟用高可靠機制,讓數據零丟失,就必須啟用 Spark Streaming 的預寫日志機制(Write Ahead Log,WAL)。該機制會同步地將接收到的 Kafka 數據寫入分布式文件系統(比如 HDFS)上的預寫日志中。所以,即使底層節點出現了失敗,也可以使用預寫日志中的數據進行恢復。
需要注意的是:
1、Kafka 中的 topic 的 partition,與 Spark 中的 RDD 的 partition 是沒有關系的。所以,在 KafkaUtils.createStream()中,提高 partition 的數量,只會增加一個 Receiver 中,讀取 partition 的線程的數量。不會增加 Spark 處理數據的並行度。
2、如果基於容錯的文件系統,比如 HDFS,啟用了預寫日志機制,接收到的數據都會被復制一份到預寫日志中。因此,在KafkaUtils.createStream()中,設置的持久化級別是 StorageLevel.MEMORY_AND_DISK_SER。
(2) 基於 Direct 的方式
使用 kafka 更加底層的 api,自己維護偏移量。
這種方式有如下優點:
1、簡化並行讀取:如果要讀取多個 partition,不需要創建多個輸入 DStream 然后對它們進行 union 操作。Spark 會創建跟 Kafka partition 一樣多的 RDD partition,並且會並行從 Kafka 中讀取數據。所以在 Kafka partition 和 RDD partition之間,有一個一對一的映射關系。
3、高性能:receiver 方式為了保證數據不丟失,需要開啟 WAL 機制,這樣同樣的數據會保存兩份。而基於 direct的方式,不依賴 Receiver,不需要開啟 WAL 機制,只要 Kafka 中作了數據的復制,那么就可以通過 Kafka 的副本進行恢復。