如何将案例class的实例作为参数传递给spark中地图内部使用的函数

How to pass instance of case class as argument to function used inside map in spark

我有这样的案例class:

case class Data(a: String, b: String, c: String);

这个数据集是这样的:

val dataset: Dataset<SomeDataset>;

并在伴随对象中运行(以防止任务不可序列化异常)

object MyObj {
   def doSomething(value: SomeDataset, data: Data //instance of case class) {...}
}

我想做这样的事情:

val data = Data(...) //instance of case class
dataset.map { doSomething(_,  data) }

在此之后,我从 spark 收到任务不可序列化异常。 如果我从 doSomething 函数中删除第二个参数,它会找到。

我什至尝试使 Data case class extends Serializable 接口,但它仍然不起作用。 像这样:

case class Data(a: String, b: String, c: String) extends Serializable

我如何让它工作?

Scala 中 case 类 和 类 的区别之一是 case 类 开箱即用地扩展 Serializable 接口:

scala> case class FirstClass()
// defined case class FirstClass

scala> val f = FirstClass()
val f: FirstClass = FirstClass()

scala> f.isInstanceOf[Serializable]
val res1: Boolean = true

scala> class SecondClass
// defined class SecondClass

scala> val s = new SecondClass()
val s: SecondClass = SecondClass@y978y4f

scala> s.isInstanceOf[Serializable] 
val res2: Boolean = false

所以现在,spark 可以通过节点(您的实例 类)序列化您的对象,但您还试图对它们进行一些操作。 Spark 也需要序列化您的操作,因为它需要在不同的节点上完成。现在 this post 可能会帮助你找出一些 TaskNotSerializableException 可能发生的场景,我的猜测是 doSomething 是一个方法,所以 spark 无法序列化它。因此,如果您可以将其定义为函数,它可能会有所帮助:

object MyObj {
  val doSomething: (SomeDataset, Data) => SomeOtherData = {...}
}