升级到Spark 2.0时的Kryo注册问题

时间:2016-11-29 13:48:38

标签: serialization apache-spark kryo

我正在将应用程序从Spark 1.6.2升级到Spark 2.0.2。这个问题与Spark无关。 Spark 1.6.2包括Kryo 2.21。 Spark 2.0.2包含Kryo 3.0.3。

应用程序将一些用Kryo序列化的数据存储在HDFS上。为了节省空间,强制执行Kryo注册。当一个类在Kryo中注册时,它会获得一个顺序ID,这个ID用于表示有线格式的类而不是完整的类名。当我们注册一个新类时,我们总是把它放在最后,所以它得到一个未使用的ID。我们也从不删除注册类。 (如果删除了一个类,我们会在其位置注册一个占位符来保留ID。)这样,ID就可以稳定,一个版本的应用程序可以读取先前版本写入的数据。

事实证明,Kryo使用相同的注册机制在其构造函数中注册基本类。在Kryo 2.21中,它注册了9个基本类,因此第一个用户注册的类获得ID 9.但是Kryo 2.22和更高版本注册了10个基本类。 (void was added.)这意味着用户注册的类从ID 10开始。

升级到Spark 2.0.2后,我们如何仍然加载旧数据?

(如果我们的第一个用户注册的类是一个已弃用的类,那就太棒了。但事实并非如此。它是scala.Tuple2[_, _]。)

1 个答案:

答案 0 :(得分:1)

实际上有Kryo.register(Class type, int id)方法可用于显式指定ID。 id参数的评论说:

  

id:必须为> = 0.较小的ID会更有效地序列化。默认情况下,ID 0-8用于基本类型和String,但这些ID可以重新利用。

自2.22以来注释错误:现在默认情况下也使用ID 9。但实际上它可以改变用途!

kryo.register(classOf[Tuple2[_, _]], 9)

正常的顺序注册适用于其他类。只有第一个类才需要显式ID。