为什么spark-shell吐出NotSerializableException而sbt控制台没有?

时间:2016-02-23 21:28:13

标签: scala apache-spark sbt

只有一个NotSerializableException我无法理解。使用Spark 1.5.0启动EMR集群,然后输入shell spark-shell --master local(如果您选择yarn-client而不是local,则没有区别。)

然后运行以下代码:

class MaybeSerializable() {
  def add(i: Int) = i + 1
}

val foo = new MaybeSerializable()

sc.makeRDD(1 to 1000).map(foo.add).reduce(_ + _)

我保证会导致org.apache.spark.SparkException: Task not serializable

现在使用相同版本的Spark "org.apache.spark" %% "spark-core" % "1.5.0"创建一个sbt项目,然后输入sbt console,然后运行

import org.apache.spark.SparkContext

val sc = new SparkContext("local", "shell")

class MaybeSerializable() {
  def add(i: Int) = i + 1
}

val foo = new MaybeSerializable()

sc.makeRDD(1 to 1000).map(foo.add).reduce(_ + _)

我向你保证它会奏效!没有例外!

如果有人能够解释这一点,我会很高兴。

1 个答案:

答案 0 :(得分:0)

关于行为的不一致,我不是Spark专家,但我会说在第一种情况下,当使用Yarn EMR时,整个“MaybeSerializable”类肯定会被序列化并被发送给执行者由司机。由于它不可序列化,因此会出现“NotSerializableException”异常。

另一方面,在第二种情况下,我不太确定该类是否被序列化,这就是为什么你没有得到异常。底层架构正在推动序列化的需要与否。当你使用sbt时,如果驱动程序没有将类的序列化版本发送到任何进程,我不会感到惊讶。在这种情况下,由于不需要,类是否可序列化并不重要。

我可以用独立的方式在我的计算机中重现第一个问题,并且我摆脱它使这个类可序列化:“类MaybeSerializable()扩展Serializable”。这是我使用(和/或匿名函数)的最佳实践,以确保我的代码将以任何集群类型运行,并且序列化行为将在集群中保持一致。

我希望它有所帮助。