想要了解一个基本问题。这是我的代码:
def createStreamingContext(sparkCheckpointDir: String,batchDuration: Int ) = {
val ssc = new StreamingContext(spark.sparkContext, Seconds(batchDuration))
ssc
}
val ssc = StreamingContext.getOrCreate(sparkCheckpointDir, () => createStreamingContext(sparkCheckpointDir, batchDuration))
val inputDirectStream = EventHubsUtils.createDirectStreams(ssc,namespace,progressDir,Map(name -> eventhubParameters)).map(receivedRecord => new String(receivedRecord.getBody))
inputDirectStream.foreachRDD { (rdd: RDD[String], time: Time) =>
val df = spark.read.json(rdd)
df.show(truncate=false)
}
ssc.start()
ssc.awaitTermination()
以上代码有效,我可以看到DF。
问题是:如果我通过
启用检查点def createStreamingContext(sparkCheckpointDir: String,batchDuration: Int ) = {
val ssc = new StreamingContext(spark.sparkContext, Seconds(batchDuration))
ssc.checkpoint(sparkCheckpointDir)
ssc
}
然后ssc.start()以"
失败已启用DStream检查点,但DStreams已启用 函数不可序列化"
我做错了什么?我想在启用检查点的情况下处理DF。
Spark版本:版本2.0.2.2.5.4.2-7 发射:spark-shell --jars spark-streaming-eventhubs_2.11-2.1.1.jar
答案 0 :(得分:0)
如果在Spark Streaming中启用了检查点,那么在foreachRDD中调用的函数中使用的对象应该是Serializable
解决方案:
- 删除jssc.checkpoint行以关闭检查点。
- 使正在使用的对象可序列化。
- 在forEachRDD函数中声明NotSerializable,因此下面的代码示例没问题:
在您的代码中,EventHubsUtils.createDirectStreams()
在做什么?也许你可以使它可序列化。
答案 1 :(得分:0)
您可以尝试将Dstream[EventHub]
转换为Dstream of type scala/java primitives
,因为序列化和反序列化由spark处理。
您正面临此序列化错误,因为在forEachRDD
中您正在使用“show”操作。
此操作通过线路将数据从执行程序提取到驱动程序,这需要序列化。您可以将其转换为Dstream of scala/java type
(如Dstream[Tuple*]
(适合您的情况)),并将EventHub
对象中的每个属性映射到元组元素。