使用Scalaz和Spark时不可序列化异常

时间:2016-02-10 20:16:20

标签: scala apache-spark scalaz

我做了一个简单的例子来尝试将scalaz library 代码与Apache Spark 1.5集成。

这是一个简单的Spark程序来说明我的问题:

package test

import org.apache.spark.{ SparkConf, SparkContext }
import org.apache.spark.rdd.RDD

import ca.crim.deti.re.spark.sparkConf
import scalaz._
import scalaz.Scalaz._

object TestSpark {

  def main(args: Array[String]) = {
    val conf = new SparkConf().setAppName("Test").setMaster("local")
    val SC = new SparkContext(conf)
    val c = SC.parallelize(List(1, 2, 3, 4, 5))

    println(func1(c).count) // WORKS
    println(func2(c).count) // DOES NOT WORK.. NotSerializableException
  }

  // WORKS!
  def func1(rdd: RDD[Int]) = {
    rdd.filter { i => f(i, i) }
  }
  // DOES NOT WORK!
  def func2[I: Equal](rdd: RDD[I]) = {
    rdd.filter { i => f(i, i) }
  }

  def f[I: Equal](i1: I, i2: I) = {
    i1 === i2
  }
}

我希望在函数定义中使用func2来使Equal工作。

在使用func2的本地模式下在Spark环境中执行时,出现以下异常:

Spark environnement exception when using scalaz

2 个答案:

答案 0 :(得分:4)

由于你的函数有一个Equal[I]约束,Spark正在关闭它并尝试在进行分发时序列化它。由于scalaz.Equal类型类不是Serializablehttps://github.com/scalaz/scalaz/blob/v7.2.0/core/src/main/scala/scalaz/Equal.scala#L10),因此Spark在运行时失败。

您可以通过使用来自Twitter的寒意库中的Serialziable来解决这个事实MeatLockerhttps://github.com/twitter/chill#the-meatlocker

或者,catsalgebra库(具有类似于上面使用的Equal类型的类)具有可序列化的类型类,您应该可以使用像您这样的类做上面没有问题。

答案 1 :(得分:0)

问题在于def func2[I: Equal](rdd: RDD[I])的调用需要范围内的Equal[I]的一些实例。由于您正在使用ScalaZ - 也许它需要来自该库的实例,显然该实例不可序列化,如堆栈跟踪中所报告的那样。

将您自己的可序列化版本的Equal [I]放入范围,这将有所帮助。