尝试在Task not serializable
中使用输入参数时出现map
错误:
val errors = inputRDD.map {
case (itemid, itemVector, userid, userVector, rating) =>
(itemid, itemVector, userid, userVector, rating,
(
(rating - userVector.dot(itemVector)) * itemVector)
- h4 * userVector
)
}
我将h4
传递给了Class的参数。
map
是一种方法,如果在我提出map
转换之前它可以正常工作:
val h4 = h4
如果我不这样做,或者把它放在方法之外,那么它就不起作用,我得到Task not serialisable
。为什么会这样?我为方法中的方法工作之外的类生成的其他val
,那么如何从输入参数/参数实例化val
呢?
答案 0 :(得分:2)
该错误表示h4
所属的类不是Serializable。
以下是一个类似的例子:
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
将成为序列化的闭包的一部分。
使Serializable类按预期工作:
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转换中this
的引用也是如此:
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)
答案 1 :(得分:0)
您可以使用广播变量。它的广播数据从你的变量到你的所有工人。有关详细信息,请访问此link。