Scala Spark:数据帧上的UDF无法序列化任务

Scala Spark:数据帧上的UDF无法序列化任务,scala,serialization,apache-spark,Scala,Serialization,Apache Spark,当我尝试在spark 1.4.1上执行以下操作时,我得到了org.apache.spark.SparkException:Task not serializable: import java.sql.{Date, Timestamp} import java.text.SimpleDateFormat object ConversionUtils { val iso8601 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX") de

当我尝试在spark 1.4.1上执行以下操作时,我得到了
org.apache.spark.SparkException:Task not serializable

import java.sql.{Date, Timestamp}
import java.text.SimpleDateFormat

object ConversionUtils {
  val iso8601 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX")

  def tsUTC(s: String): Timestamp = new Timestamp(iso8601.parse(s).getTime)

  val castTS = udf[Timestamp, String](tsUTC _)
}

val df = frame.withColumn("ts", ConversionUtils.castTS(frame("ts_str")))
df.first
这里,
frame
是一个
DataFrame
,它位于
HiveContext
中。该数据帧没有任何问题

我有类似的整数自定义项,它们工作没有任何问题。然而,带有时间戳的那个似乎会引起问题。根据,
java.sql.TimeStamp
实现了
Serializable
,所以这不是问题所在。可以看出,
SimpleDateFormat
也是如此

这让我相信是UDF造成了问题。然而,我不知道该怎么做,如何修复它

跟踪的相关部分:

Caused by: java.io.NotSerializableException: ...
Serialization stack:
        - object not serializable (class: ..., value: ...$ConversionUtils$@63ed11dd)
        - field (class: ...$ConversionUtils$$anonfun$3, name: $outer, type: class ...$ConversionUtils$)
        - object (class ...$ConversionUtils$$anonfun$3, <function1>)
        - field (class: org.apache.spark.sql.catalyst.expressions.ScalaUdf$$anonfun$2, name: func$2, type: interface scala.Function1)
        - object (class org.apache.spark.sql.catalyst.expressions.ScalaUdf$$anonfun$2, <function1>)
        - field (class: org.apache.spark.sql.catalyst.expressions.ScalaUdf, name: f, type: interface scala.Function1)
        - object (class org.apache.spark.sql.catalyst.expressions.ScalaUdf, scalaUDF(ts_str#2683))
        - field (class: org.apache.spark.sql.catalyst.expressions.Alias, name: child, type: class org.apache.spark.sql.catalyst.expressions.Expression)
        - object (class org.apache.spark.sql.catalyst.expressions.Alias, scalaUDF(ts_str#2683) AS ts#7146)
        - element of array (index: 35)
        - array (class [Ljava.lang.Object;, size 36)
        - field (class: scala.collection.mutable.ArrayBuffer, name: array, type: class [Ljava.lang.Object;)
        - object (class scala.collection.mutable.ArrayBuffer,
原因:java.io.NotSerializableException:。。。
序列化堆栈:
-对象不可序列化(类:…,值:…$ConversionUtils$@63ed11dd)
-字段(类:…$ConversionUtils$$anonfun$3,名称:$outer,类型:class…$ConversionUtils$)
-对象(类…$ConversionUtils$$anonfun$3,)
-字段(类:org.apache.spark.sql.catalyst.expressions.ScalaUdf$$anonfun$2,名称:func$2,类型:interface scala.Function1)
-对象(类org.apache.spark.sql.catalyst.expressions.ScalaUdf$$anonfun$2,)
-字段(类:org.apache.spark.sql.catalyst.expressions.ScalaUdf,名称:f,类型:interface scala.Function1)
-对象(类org.apache.spark.sql.catalyst.expressions.ScalaUdf,ScalaUdf(ts#u str#2683))
-字段(类:org.apache.spark.sql.catalyst.expressions.Alias,名称:child,类型:class org.apache.spark.sql.catalyst.expressions.Expression)
-对象(类org.apache.spark.sql.catalyst.expressions.Alias,scalaUDF(ts#u str#2683)为ts#7146)
-数组元素(索引:35)
-数组(类[Ljava.lang.Object;,大小36)
-字段(类:scala.collection.mutable.ArrayBuffer,名称:数组,类型:class[Ljava.lang.Object;)
-对象(类scala.collection.mutable.ArrayBuffer,
试试:


@CharlieRosenfeld一个对象需要序列化才能发送到处理节点。因此,需要在节点上运行的函数需要在可序列化对象上定义,就像一个符咒一样工作。谢谢@DavidGriffin,尽管我想知道为什么会发生这种情况。你能评论一些链接,其中清楚地解释了这个问题吗?@ChaitanyaVemulakonda关于它有一篇深入的文章(方法基本上需要使父对象可序列化,以便将它们发送给执行者)
object ConversionUtils extends Serializable {
  ...
}