我需要根据来自Kafka的处理数据使用GraphX构建图形。但是,似乎sc.parallelize()
引发了错误java.io.NotSerializableException: org.apache.spark.SparkContext
......
val messages = KafkaUtils.createDirectStream[String, String, StringDecoder, StringDecoder](
ssc, kafkaParams, topicsSet)
val lines = messages.map(_._2)
lines.foreachRDD(rdd => {
rdd.foreachPartition(partition => {
......
// Build a graph
val vertRDD = sc.parallelize(vertices)
val edgeRDD = sc.parallelize(edge)
val graph = Graph(vertRDD, edgeRDD, defaultUser)
}
})
})
我应该以什么方式解决问题?
答案 0 :(得分:1)
foreachRDD运算符在驱动程序上每个批处理间隔运行处理RDD,然后使用它(通过其RDD
)来编写最终将自身转换为Spark作业的代码。
foreachRDD(foreachFunc:(RDD [T])⇒单位):单位将一个函数应用于此DStream中的每个RDD。这是一个输出操作符,因此'this'DStream将被注册为输出流,因此具体化。
RDD.foreachPartition是一种只会在执行者身上发生的动作。
foreachPartition(f:(Iterator [T])⇒Unit):Unit 将函数
f
应用于此RDD的每个分区。
在任务可以在执行程序上执行之前,它必须被序列化,因为SparkContext
不可序列化,因此是例外。这就是Spark如何确保SparkContext
(因为sc
)永远不会出现由于Spark中的设计决策。这无论如何都没有意义,因为整个调度基础设施都在驱动程序上。
SparkContext
和RDD
仅适用于驱动程序。它们只是描述分布式计算的一种方式,最终将“转换”为在Spark执行程序上运行的任务。
这就是您看到错误消息的原因:
顺便说一下,我今天回答了类似的问题(见Can SparkContext.textFile be used with a custom receiver?),所以看起来今天是SparkContext日:)java.io.NotSerializableException:org.apache.spark.SparkContext