Scala:RDD映射中的任务不可序列化由json4s“隐式val格式= DefaultFormats”引起

Posted

技术标签:

【中文标题】Scala:RDD映射中的任务不可序列化由json4s“隐式val格式= DefaultFormats”引起【英文标题】:Scala: Task not serializable in RDD map Caused by json4s "implicit val formats = DefaultFormats" 【发布时间】:2017-11-03 07:23:01 【问题描述】:

以下程序尝试为每个 ROW(在 RDD 映射中)调用 3 个函数:

    import org.json4s._
    import org.json4s.jackson.JsonMethods._
    implicit val formats = DefaultFormats

    class TagCalculation extends Serializable 
    def test1(x: String) = x + " test1"
    def test2(x: String) = x + "test2" 
    def test3(x: String) = x + "test3" 
    def test5(arg1: java.lang.Integer, arg2: String, arg3: scala.collection.immutable.$colon$colon[Any]) = "test mix2"
  
  val df = sqlContext.createDataFrame(Seq((1,"android"), (2, "iPhone")))
  val get_test = new TagCalculation
  val field = Array("test1","test2","test3")

  val bb = df.rdd.map(row => 

    val reValue1 = "start"
    val ret = for(every <- field)
      yield 
        val test_para = Array(reValue1)
        val argtypes = test_para.map(_.getClass)
        val method4 = get_test.getClass.getMethod(every, argtypes: _*)

        val bbq = method4.invoke(get_test, test_para: _*)

        if (field.last == every)
            bbq
      
    ret.last
  )

但有些错误输出:

org.apache.spark.SparkException:任务不可序列化 org.apache.spark.util.ClosureCleaner$.ensureSerializable(ClosureCleaner.scala:304) 在 org.apache.spark.util.ClosureCleaner$.org$apache$spark$util$ClosureCleaner$$clean(ClosureCleaner.scala:294) 在 org.apache.spark.util.ClosureCleaner$.clean(ClosureCleaner.scala:122) 在 org.apache.spark.SparkContext.clean(SparkContext.scala:2032) 在 org.apache.spark.rdd.RDD$$anonfun$map$1.apply(RDD.scala:314) 在 org.apache.spark.rdd.RDD$$anonfun$map$1.apply(RDD.scala:313) 在 org.apache.spark.rdd.RDDOperationScope$.withScope(RDDOperationScope.scala:147) 在 org.apache.spark.rdd.RDDOperationScope$.withScope(RDDOperationScope.scala:108) 在 org.apache.spark.rdd.RDD.withScope(RDD.scala:306) 在 org.apache.spark.rdd.RDD.map(RDD.scala:313) ........ at org.apache.spark.deploy.SparkSubmit$.submit(SparkSubmit.scala:205) at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:120) 在 org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala) 原因: java.io.NotSerializableException: org.json4s.DefaultFormats$

任何指针?


这可能是由“隐式 val 格式 = DefaultFormats”引起的。但我需要在“地图”之前提取价值。

【问题讨论】:

【参考方案1】:

问题是因为您在 calling class 中定义 TagCalculation 类,您在其中初始化和使用对象。只需将其移出calling class 或将其设为separate class 即可解决NotSerializableException 的问题。

【讨论】:

以上是关于Scala:RDD映射中的任务不可序列化由json4s“隐式val格式= DefaultFormats”引起的主要内容,如果未能解决你的问题,请参考以下文章

基于Scala中另一列的值映射RDD列

任务不可序列化错误:Spark

Scala 错误:线程“主”org.apache.spark.SparkException 中的异常:任务不可序列化

Spark Scala:任务不可序列化错误

任务在 Databricks 上的 Scala 中不可序列化

如何将 RDD [GenericRecord] 转换为 scala 中的数据框?