一.原因分析
當Spark從1.x升級到2.x時,如果使用SparkStreaming加載Kafka的數據,即使Kafka版本沒有變化【一般會有所升級】,對應的spark-streaming-kafka也必須升級到對應版本,訪問方式也會有所變化。
此處是從Spark1.6.0升級到Spark2.4.3,Kafka略有升級【從2.1.0升級到2.2.1】,初始使用的是:
import org.apache.spark.streaming.kafka.KafkaUtils
val dframe = KafkaUtils.createDirectStream[String, String, StringDecoder, StringDecoder](ssc, kafkaParams, topic)
來加載數據的,當升級後,就算是更換對應的spark-streaming-kafka-0-10_2.11-2.4.3還是會報錯,報錯信息如下:
Spark Streaming: java.lang.NoClassDefFoundError:kafka/api/TopicMetadataRequest
或者是各種類找不到!
二.解決方案
此時就需要更換新的訪問方式:
import org.apache.spark.streaming.kafka010.ConsumerStrategies.Subscribe
import org.apache.spark.streaming.kafka010.KafkaUtils
import org.apache.spark.streaming.kafka010.LocaltionStrategies.PreferConsistent
val dframe = KafkaUtils.createDirectStream[String, String](ssc, PreferConsistent, Subscribe[String, String](topic, kafkaParams))
三.注意事項
1.spark1.6.0使用方式:
dframe.foreachRDD(rdd =>{
rdd.foreachPartition(partition =>{
partition.foreach(record => {
val key = record._1
val value = record._2
}
}
}
2.spark2.4.x使用方式:
dframe.foreachRDD(rdd =>{
rdd.foreachPartition(partition =>{
partition.foreach(record => {
val key = record.key()
val value = record.value()
}
}
}
備註:kafka裏面的每條數據都是按照(key, value)存儲的。