- 更新時間:2019-08-29
錯誤描述
今天在寫spark程序時,遇到task not serializable的報錯,提示task未進行序列化。
在正常spark程序在執行時會進行task序列化,當一些函數裏面有外部變量時,不會序列化外部變量,由此報錯。
上面報錯的主要原因是在map函數的閉包內引入外部函數,外部變量沒有進行序列化,我的代碼結構如下:
def test(sc: SparkContext, rdd1: RDD[((String, String), Float)], rdd2: [((String, String), Float)], isFunc: Boolean): Unit = {
val rdd_joined = rdd1.leftOuterJoin(rdd2).map({ x =>
if (x._2._2.getOrElse(0) != 0 ) (x._1._1, (x._1._2, if(isFunc == false) 1 else Func(0).toFloat))
else (x._1._1, (x.1._2, 0.0.toFloat))
}).filter(_._2._2 != 0.0)
... ...
}
def Func(z: Float): Float = {
z
}
解決辦法
(1)不在map這類函數的閉包內引入外部變量
(2)如果一定要引入,提前對相應的類做好序列化操作
由於上面報錯是因爲在map閉包內引入了Func函數,所以乾脆把Func函數放到map中,這樣就修復了,如下:
def test(sc: SparkContext, rdd1: RDD[((String, String), Float)], rdd2: [((String, String), Float)], isFunc: Boolean): Unit = {
val rdd_joined = rdd1.leftOuterJoin(rdd2).map({ x =>
def Func(z: Float): Float = {
z
}
if (x._2._2.getOrElse(0) != 0 ) (x._1._1, (x._1._2, if(isFunc == false) 1 else Func(0).toFloat))
else (x._1._1, (x.1._2, 0.0.toFloat))
}).filter(_._2._2 != 0.0)
... ...
}
參考:
https://bbs.csdn.net/topics/390844956
https://blog.csdn.net/qq_38899793/article/details/80351205
https://blog.csdn.net/achilles12345/article/details/77778431
https://blog.csdn.net/javastart/article/details/51206715