只有一个NotSerializableException
我不明白。使用Spark 1.5.0启动EMR集群,然后输入shell spark-shell --master local
(如果您选择yarn-client
而不是local
,则不会产生任何影响)。为什么spark-shell吐出NotSerializableException而sbt控制台没有?
然后运行下面的代码:
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
现在创建使用星火"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(_ + _)
我向你保证它会起作用!没有例外!
如果有人能解释这一点,我会非常高兴。
我建议避免使用'extends Serializable'和用例类来确保数据和函数之间清晰分离。你必须小心把'extends Serializable'放在任何地方,因为这会造成内存泄漏。无论如何,我仍然不明白为什么在SBT控制台中运行Spark是不同的。我不认为Spark是SBT意识到的! – samthebest
正如您所说,使用数据类别来确保数据清晰分离。对于使用对象的函数,通常具有比可序列化类更好的性能。如果将MaybeSerializable定义为对象,则可以通过另一种方式以高性能方式摆脱“不可序列化”的“任务不可序列化”异常。 – MiguelPeralvo