本文將介紹如何使用Spark 1.3.0引入的Direct API從Kafka中讀資料。
和基於Receiver接收資料不一樣,這種方式定期地從Kafka的topic+partition中查詢最新的偏移量,再根據定義的偏移量範圍在每個batch裡面處理資料。當作業需要處理的資料來臨時,spark通過呼叫Kafka的簡單消費者API讀取一定範圍的資料。這個特性目前還處於試驗階段,而且僅僅在Scala和Java語言中提供相應的API。
和基於Receiver方式相比,這種方式主要有一些幾個優點:
(1)、簡化並行。我們不需要建立多個Kafka 輸入流,然後union他們。而使用directStream,Spark Streaming將會建立和Kafka分割槽一樣的RDD分割槽個數,而且會從Kafka並行地讀取資料,也就是說Spark分割槽將會和Kafka分割槽有一一對應的關係,這對我們來說很容易理解和使用;
(2)、高效。第一種實現零資料丟失是通過將資料預先儲存在WAL中,這將會複製一遍資料,這種方式實際上很不高效,因為這導致了資料被拷貝兩次:一次是被Kafka複製;另一次是寫到WAL中。但是本文介紹的方法因為沒有Receiver,從而消除了這個問題,所以不需要WAL日誌;
(3)、恰好一次語義(Exactly-once semantics)。《Spark Streaming和Kafka整合開發指南(一)》文章中通過使用Kafka高層次的API把偏移量寫入Zookeeper中,這是讀取Kafka中資料的傳統方法。雖然這種方法可以保證零資料丟失,但是還是存在一些情況導致資料會丟失,因為在失敗情況下通過Spark
Streaming讀取偏移量和Zookeeper中儲存的偏移量可能不一致。而本文提到的方法是通過Kafka低層次的API,並沒有使用到Zookeeper,偏移量僅僅被Spark Streaming儲存在Checkpoint中。這就消除了Spark Streaming和Zookeeper中偏移量的不一致,而且可以保證每個記錄僅僅被Spark Streaming讀取一次,即使是出現故障。
但是本方法唯一的壞處就是沒有更新Zookeeper中的偏移量,所以基於Zookeeper的Kafka監控工具將會無法顯示消費的狀況。然而你可以通過Spark提供的API手動地將偏移量寫入到Zookeeper中。如何使用呢?其實和方法一差不多
1、引入依賴。
對於Scala和Java專案,你可以在你的pom.xml檔案引入以下依賴:
2 |
<groupId>org.apache.spark</groupId> |
3 |
<artifactId>spark-streaming-kafka_2. 10 </artifactId> |
4 |
<version> 1.3 . 0 </version> |
如果你是使用SBT,可以這麼引入:
1 |
libraryDependencies
+= "org.apache.spark" % "spark-streaming-kafka_2.10" % "1.3.0" |
2、程式設計
在Streaming應用程式程式碼中,引入KafkaUtils ,並建立DStream輸入流:
1 |
import org.apache.spark.streaming.kafka. _ |
3 |
val directKafkaStream = KafkaUtils.createDirectStream[ |
4 |
[key class ],
[value class ],
[key decoder class ],
[value decoder class ]
]( |
5 |
streamingContext,
[map of Kafka parameters], [set of topics to consume]) |
在 Kafka parameters引數中,你必須指定 metadata.broker.list或者bootstrap.servers引數。在預設情況下,Spark Streaming將會使用最大的偏移量來讀取Kafka每個分割槽的資料。如果你配置了auto.offset.reset為smallest,那麼它將會從最小的偏移量開始消費。
當然,你也可以使用KafkaUtils.createDirectStream的另一個版本從任意的位置消費資料。如果你想回去每個batch中Kafka的偏移量,你可以如下操作:
1 |
directKafkaStream.foreachRDD
{ rdd = > |
2 |
val offsetRanges = rdd.asInstanceOf[HasOffsetRanges] |
你可以通過這種方式來手動地更新Zookeeper裡面的偏移量,使得基於Zookeeper偏移量的Kafka監控工具可以使用。
還有一點需要注意,因為這裡介紹的方法沒有使用到Receiver,所以Spark中關於spark.streaming.receiver.*相關的配置引數將不會對建立DStreams 有影響。我們可以使用spark.streaming.kafka.*引數進行配置。
3、部署
對應任何的Spark 應用,我們都是用spark-submit
來啟動你的應用程式,對於Scala和Java使用者,如果你使用的是SBT或者是Maven,你可以將spark-streaming-kafka_2.10及其依賴打包進應用程式的Jar檔案中,並確保spark-core_2.10和
spark-streaming_2.10標記為provided,因為它們在Spark 安裝包中已經存在:
02 |
<groupId>org.apache.spark</groupId> |
03 |
<artifactId>spark-streaming _ 2.10 </artifactId> |
04 |
<version> 1.3 . 0 </version> |
05 |
<scope>provided</scope> |
09 |
<groupId>org.apache.spark</groupId> |
10 |
<artifactId>spark-core _ 2.10 </artifactId> |
11 |
<version> 1.3 . 0 </version> |
12 |
<scope>provided</scope> |
然後使用spark-submit來啟動你的應用程式。
本文翻譯自:https://spark.apache.org/docs/latest/streaming-kafka-integration.html
尊重原創,轉載請註明: 轉載自過往記憶(http://www.iteblog.com/)
本文連結地址: 《Spark Streaming和Kafka整合開發指南(二)》(http://www.iteblog.com/archives/1326)