Apache Spark - org.apache.spark.SparkException:任务不可序列化

时间:2015-03-24 14:39:59

标签: apache-spark rdd gradient-descent

尝试运行我的方法时:

    def doGD() = {
       allRatings.foreach(rating => gradientDescent(rating));
    }

我收到错误:org.apache.spark.SparkException: Task not serialisable

据我所知,我的Gradient Descent方法不会并行化,因为每一步都取决于前一步 - 所以并行工作不是一种选择。但是,如果我这样做,请从控制台:

    val gd = new GradientDescent()
    gd.doGD();

我收到了上述错误。

但是,如果在控制台中我执行此操作:

    val gd = new GradientDescent()
    gd.allRatings.foreach(rating => gradientDescent(rating))

它完美无缺。您可能已经注意到第二个示例中的代码与第一个示例中的代码相同,除了代替方法之外,我只是从代码中取出代码并直接调用它。

为什么一个工作而另一个不工作?我很困惑。

(附加说明:班级GradientDescent extends Serializable)。

gradientDescent方法:

def gradientDescent(rating : Rating) = { 

var userVector = userFactors.get(rating.user).get
var itemVector = itemFactors.get(rating.product).get

userFactors.map(x => if(x._1 == rating.user)(x._1, x._2 += 0.02 * (calculatePredictionError(rating.rating, userVector, itemVector) * itemVector)))
userVector = userFactors.get(rating.user).get // updated user vector

itemFactors.map(x => if(x._1 == rating.product)(x._1, x._2 += 0.02 * (calculatePredictionError(rating.rating, userVector, itemVector) * itemVector)))
}

我知道我使用存储在主服务器上的2个变量 - userFactorsitemFactors - 并且由于过程是顺序并行化是不可能的。但是,这并不能解释为什么从控制台调用该方法不起作用,而是在控制台中重写方法的内容。

1 个答案:

答案 0 :(得分:0)

很难说没有GradientDescent类的完整来源,但你可能正在捕获一个不可序列化的值。运行该方法时,需要序列化整个对象并将其发送给worker,而内联版本则不需要。

相关问题