2016-11-29 116 views
1

我正在将Spark 1.6.2的应用程序升级到Spark 2.0.2。这个问题并不严格与Spark有关。 Spark 1.6.2包含Kryo 2.21。 Spark 2.0.2包含Kryo 3.0.3。升级到Spark 2.0时出现Kryo注册问题

应用程序存储一些使用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[_, _]。)

+0

Kryo怎么可能做出这样一个突破性变化,从2.21变为2.22?为了增加伤害,他们的更新日志列出了每个发行版的序列化兼容性为“是”。但更新日志开始于2.22。 –

+0

好的,解决方法不是太糟糕。我认为我在那里过于戏剧化。 –

回答

1

其实是有一个Kryo.register(Class type, int id)方法,其可用于明确指定的ID 。对于id参数评论说:

ID:必须> = 0较小ID被更有效地序列化。默认情况下,基元类型和String使用ID 0-8,但可以重新使用这些ID。

从2.22开始的评论是错误的:ID 9现在也被默认使用。但事实上它可以重新使用!

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

正常的顺序注册适用于其余类。显式ID只对第一类是必需的。

相关问题