org.apache.spark.SparkException:任务不可序列化。如何在map {}中运行方法

时间:2016-10-20 15:35:00

标签: scala apache-spark rdd

我尝试在值上调用方法。但是得到一个错误。我的方法。

processDate(p(2))

值看起来有点像 20160125204123

这是我的班级。

class ScalaJob(sc: SparkContext) {
  def run(filePath: String) : RDD[(String, String, String)] = {
    //pass the file
    val file = sc.textFile(filePath);
    //find values in every raw
    val values = file.map{
      dataRaw =>
      val p = dataRaw.split("[|]",-1)
      (p(1), processDate(p(2)), p(32))
    }

我的方法应该返回一个字符串

def processDate(s: String) : String = {

有没有办法让它发挥作用?

2 个答案:

答案 0 :(得分:1)

在这种情况下RDD.map file.map内使用的任何代码都将被序列化并运送给执行者。因此,为了实现这一点,代码应该是可序列化的。在这种情况下,您使用了在其他地方定义的方法processDate。确保定义方法的类是可序列化的。注意:您需要使整个依赖关系链可序列化。一个快速选项是将processDate绑定到val作为函数,并在RDD内使用它。或者在对象中定义方法。例如:

class ScalaJob(sc: SparkContext) {
  def run(filePath: String): RDD[(String, String, String)] = {
    //pass the file
    val file = sc.textFile(filePath);
   //find values in every raw
    val process = processDate _
    val values = file.map {
      dataRaw =>
        val p = dataRaw.split("[|]", -1)
        (p(1), process(p(2)), p(32))
    }
  }
}

有关详细信息,请参阅Spark Task Not Serializable

答案 1 :(得分:1)

错误即将发生,因为本质上不可序列化的Revert 。 Spark会尝试发送closure的整个ScalaJob,其中包含sc: SparkContext。这就是问题所在。解决方法是sc

你的课程定义应该是这样的

sc @transient