Apache spark org.apache.spark.SparkException:任务不可序列化-使用参数时
尝试在Apache spark org.apache.spark.SparkException:任务不可序列化-使用参数时,apache-spark,rdd,Apache Spark,Rdd,尝试在映射中使用输入参数时,我收到一个任务不可序列化的错误: val errors = inputRDD.map { case (itemid, itemVector, userid, userVector, rating) => (itemid, itemVector, userid, userVector, rating, ( (rating - userVector.dot(itemVector)) * itemVector
映射中使用输入参数时,我收到一个任务不可序列化的错误:
val errors = inputRDD.map {
case (itemid, itemVector, userid, userVector, rating) =>
(itemid, itemVector, userid, userVector, rating,
(
(rating - userVector.dot(itemVector)) * itemVector)
- h4 * userVector
)
}
我将h4
与类的参数一起传入
map
是一种方法,如果在map
转换之前,我输入了以下内容,则它可以正常工作:
val h4 = h4
如果我不这样做,或者把它放在方法之外,那么它就不工作了,我得到了任务不可序列化
。为什么会发生这种情况?我为方法外部的类生成的其他val
在方法内部工作,那么当从输入参数/参数实例化val
时,它为什么没有呢?错误表明h4
所属的类不可序列化
下面是一个类似的例子:
class ABC(h: Int) {
def test(s:SparkContext) = s.parallelize(0 to 5).filter(_ > h).collect
}
new ABC(3).test(sc)
//org.apache.spark.SparkException: Job aborted due to stage failure:
// Task not serializable: java.io.NotSerializableException:
// $iwC$$iwC$$iwC$$iwC$$iwC$$iwC$$iwC$$iwC$ABC
当在rdd转换中使用this.h
时,this
将成为序列化的闭包的一部分
使类可序列化按预期工作:
class ABC(h: Int) extends Serializable {
def test(s:SparkContext) = s.parallelize(0 to 5).filter(_ > h).collect
}
new ABC(3).test(sc)
// Array[Int] = Array(4, 5)
通过在方法中定义局部变量,在rdd转换中删除对该
的引用也是如此:
class ABC(h: Int) {
def test(s:SparkContext) = {
val x = h;
s.parallelize(0 to 5).filter(_ > x).collect
}
}
new ABC(3).test(sc)
// Array[Int] = Array(4, 5)
您可以使用广播变量。它将变量中的数据广播给所有工作人员。有关更多详细信息,请访问此项。h4
是在单独的类中声明的变量吗?如果是,则尝试从可序列化接口扩展该类。h4是什么类型?它是可序列化的吗?h4
是在类中声明的,并且是Double吗?我的印象是Double
是可序列化的h4
是一个Double
。还有什么想法吗?谢谢@monster是的,Double是可序列化的,h4
是Double。要点是:它是一个类的成员,因此h4
是this.h4
的缩写,其中this
指的是类的对象。当使用this.h4
时,此
被拉入序列化的闭包中,因此需要使类可序列化;而且,这都是在一个类。这有区别吗?@monsterval errors
和h4
是同一类的成员(它扩展了可序列化的)@monster在这种情况下,该类可能包含一些其他不可序列化的成员。