提问者:小点点

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


尝试运行我的方法时:

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

我得到了错误:<code>org.apache.spark。SparkException:任务不可串行化

我知道我的梯度下降方法不会平行进行,因为每一步都取决于前一步-所以并行工作不是一个选项。但是,如果我这样做,请从控制台:

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

我得到了上面提到的错误。

但是,如果在Console中执行此操作:

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

它工作得很好。您可能已经注意到,第二个示例中有效的代码与第一个示例中的代码相同,只是我只是将代码从方法中取出并直接调用它,而不是方法。

为什么一个有效而另一个无效?我很困惑。

(附加说明:Class<code>GradientDescent扩展了Serializable</code>)。

gradientDesent方法:

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)))
}

我知道我使用了存储在master上的两个变量- userFactors和< code>itemFactors -由于该过程是连续的,因此不可能进行并行化。但是这并不能解释为什么从控制台调用方法不起作用,但是在控制台中重写方法的内部却可以。


共1个答案

匿名用户

如果没有 GradientDescent 类的完整源代码,很难分辨,但您可能正在捕获一个不可序列化的值。运行该方法时,它需要序列化完整对象并将其发送给工作线程,而内联版本则不需要。