当类扩展Serializable时,Apache Spark任务不可序列化

时间:2015-04-12 14:41:35

标签: scala serialization apache-spark rdd

我一直有关于Task not Serializable的错误。

我已经创建了一个小类,它扩展了Serializable - 我认为当你需要序列化值时,我认为是这种情况。

class SGD(filePath : String) extends Serializable {

 val rdd = sc.textFile(filePath)
 val mappedRDD = rdd.map(x => x.split(" ")
                    .slice(0,3))
                    .map(y => Rating(y(0).toInt, y(1).toInt, y(2).toDouble))
                    .cache

 val RNG = new Random(1)
 val factorsRDD = mappedRDD(x => (x.user, (x.product, x.rating)))
                 .groupByKey
                 .mapValues(listOfItemsAndRatings => 
                                             Vector(Array.fill(2){RNG.nextDouble}))
}

最后一行总是会导致Task not Serializable错误。我不明白的是:Class是Serializable;并且,类Random也可以根据API进行序列化。那么,我做错了什么?我一直无法得到这样的东西去工作;因此,我想我的理解是错误的。我一直被告知Class必须是Serializable ......好吧它仍然无效!?

1 个答案:

答案 0 :(得分:7)

2.11.0-M2之前,

scala.util.Random不可序列化。

很可能您使用的是早期版本的Scala。

一个类在其所有成员都是Serializable之前不会变为Serializable(或者提供了一些其他机制来序列化它们,例如transientreadObject/writeObject。)

在spark-1.3中运行给定示例时,我得到以下stacktrace:

Caused by: java.io.NotSerializableException: scala.util.Random
Serialization stack:
    - object not serializable (class: scala.util.Random, value: scala.util.Random@52bbf03d)
    - field (class: $iwC$$iwC$SGD, name: RNG, type: class scala.util.Random)

解决这个问题的一种方法是在mapValues中对随机变量进行实例化:

mapValues(listOfItemsAndRatings => { val RNG = new Random(1)
                   Vector(Array.fill(2)(RNG.nextDouble)) })