序列化Spark的Scalaz顺序

时间:2016-12-21 20:59:29

标签: scala serialization apache-spark scalaz

我注意到大多数Scalaz类都不可序列化。在这种情况下,我尝试使用类型类在Spark中自定义排序数组。

reduce示例可能是这样的:

> val ord = Order[T]{ ... } 
> sc.makeRDD[T](...).grupBy(...).map { 
    case (_, grouped) => IList[T](grouped.toList).sorted(ord).distinct(ord)
  }

正如您所料,此实现会引发NotSerializableException,因为Order[T]不可序列化。

有没有办法让Order[T]可序列化?在一个完美的世界里,我希望仍然使用scalaz避免这个问题。在一个不那么完美的中,我可以考虑其他实现。

如果发生这种情况,必须以可持续和可扩展的方式保持自定义排序和不同的实现。

1 个答案:

答案 0 :(得分:6)

如果您需要访问某些不可序列化的对象,可以将其包装在object中:

scala> class NotSerializablePrinter { def print(msg:String) = println(msg) }
defined class NotSerializablePrinter

scala> val printer = new NotSerializablePrinter
printer: NotSerializablePrinter = $iwC$$iwC$NotSerializablePrinter@3b8afdbf

scala> val rdd = sc.parallelize(Array("1","2","3"))
rdd: org.apache.spark.rdd.RDD[String] = ParallelCollectionRDD[24] at parallelize at <console>:30

scala> rdd.foreach(msg => printer.print(msg)) // Fails
org.apache.spark.SparkException: Task not serializable
...

scala> object wrap { val printer = new NotSerializablePrinter }
defined module wrap

scala> rdd.foreach(msg => wrap.printer.print(msg))
1
3
2

在您的情况下,您将使用Scalaz NotSerializablePrinter实例替换我的Order实例。此示例来自this useful article(第3a项)。