【发布时间】:2016-11-14 20:01:02
【问题描述】:
为了测试 Spark 中的序列化异常,我以 2 种方式编写了一个任务。
第一种方式:
package examples
import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
object dd {
def main(args: Array[String]):Unit = {
val sparkConf = new SparkConf
val sc = new SparkContext(sparkConf)
val data = List(1,2,3,4,5)
val rdd = sc.makeRDD(data)
val result = rdd.map(elem => {
funcs.func_1(elem)
})
println(result.count())
}
}
object funcs{
def func_1(i:Int): Int = {
i + 1
}
}
这种方式 spark 效果很好。
当我将其更改为以下方式时,它不起作用并抛出 NotSerializableException。
第二种方式:
package examples
import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
object dd {
def main(args: Array[String]):Unit = {
val sparkConf = new SparkConf
val sc = new SparkContext(sparkConf)
val data = List(1,2,3,4,5)
val rdd = sc.makeRDD(data)
val handler = funcs
val result = rdd.map(elem => {
handler.func_1(elem)
})
println(result.count())
}
}
object funcs{
def func_1(i:Int): Int = {
i + 1
}
}
我知道我收到错误“任务不可序列化”的原因是因为我试图在第二个示例中将一个不可序列化的对象 funcs 从驱动程序节点发送到工作程序节点。对于第二个例子,如果我让对象funcs 扩展Serializable,这个错误就会消失。
但在我看来,因为funcs 是一个对象而不是一个类,所以它是一个单例,应该被序列化并从驱动程序传送到工作程序,而不是在工作程序节点本身内实例化。在这种情况下,虽然使用对象funcs 的方式不同,但我猜想在这两个示例中,不可序列化对象funcs 是从驱动节点传送到工作节点的。
我的问题是为什么第一个示例可以成功运行,但第二个示例失败并出现“任务不可序列化”异常。
【问题讨论】:
标签: serialization apache-spark rdd