Spark Kryo序列化失败

3

我有一段Spark代码,在Spark 1.3上运行正常,但当我将其移植到Spark 1.5.2时失败了(集群升级超出我的控制)。失败的信息如下:

Caused by: java.io.NotSerializableException: com.location.model.Profile
Serialization stack:
    - object not serializable (class: com.location.model.Profile, value: com.location.model.Profile@596032b0)
    - field (class: org.apache.spark.rdd.PairRDDFunctions$$anonfun$aggregateByKey$1, name: zeroValue$3, type: class java.lang.Object)
    - object (class org.apache.spark.rdd.PairRDDFunctions$$anonfun$aggregateByKey$1, <function0>)
    - field (class: org.apache.spark.rdd.PairRDDFunctions$$anonfun$aggregateByKey$1$$anonfun$1, name: $outer, type: class org.apache.spark.rdd.PairRDDFunctions$$anonfun$aggregateByKey$1)
    - object (class org.apache.spark.rdd.PairRDDFunctions$$anonfun$aggregateByKey$1$$anonfun$1, <function0>)
    - field (class: org.apache.spark.rdd.PairRDDFunctions$$anonfun$aggregateByKey$1$$anonfun$apply$10, name: createZero$1, type: interface scala.Function0)
    - object (class org.apache.spark.rdd.PairRDDFunctions$$anonfun$aggregateByKey$1$$anonfun$apply$10, <function1>)
    at org.apache.spark.serializer.SerializationDebugger$.improveException(SerializationDebugger.scala:40)
    at org.apache.spark.serializer.JavaSerializationStream.writeObject(JavaSerializer.scala:47)
    at org.apache.spark.serializer.JavaSerializerInstance.serialize(JavaSerializer.scala:84)
    at org.apache.spark.util.ClosureCleaner$.ensureSerializable(ClosureCleaner.scala:301)

有趣的一点是,手头的这个类Profile被声明为class Profile() extends KryoSerializable并覆盖了该接口的读/写方法。
我还将此配置设置为Spark-submit:"--conf" -> "'spark.serializer=org.apache.spark.serializer.KryoSerializer'",并通过conf.registerKryoClasses(Array(classOf[Profile], ...注册了Profile类。
所以一切都按照Spark Tunning guide中的说明进行操作,之前运行得很好。 请注意,异常显示ClosureCleaner正在使用JavaSerializerInstance,如果我将Profile类添加extends Serializable,它确实可以工作。但我不确定为什么它在使用那个序列化程序,也不知道为什么我需要与Java Serialization兼容,如果我明确要求使用Kryo。
编辑:我甚至完全删除了参数,因为在registerKryoClasses下的代码无论如何都会设置该属性。实际上,我怀疑正在使用Kryo序列化(我在write内部添加了println并出现了,但某种先前的验证不正确)。
1个回答

0

你尝试过在提交时去掉单引号吗?我认为应该是:

--conf "spark.serializer=org.apache.spark.serializer.KryoSerializer"

你是不是通过Luigi提交的?


我在询问如何删除包裹您的配置参数的单引号,而不是完全删除它。 - Igor Berman
相同的效果,基本上是在说明配置是否被正确设置。 - Daniel Langdon
是的,确实。我能想到另一个问题 - 为什么要注册Profile数组而不是Profile本身? - 看起来Spark在某些具有Profile参数的闭包中存在问题(来自堆栈跟踪)。 - Igor Berman
我不需要 registerKryoClasses 期望注册一个类数组。Profile 只是这些类中的第一个。你提到的看起来像是 classOf [Array [Profile]]。不过还是感谢你的帮助 :-) - Daniel Langdon
很遗憾,这里没有涉及到闭包,实际上第107行是.aggregateByKey(new Profile(), 3200),我只是提供了一个零值 :-( - Daniel Langdon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接