使用 Kryo 时,通常建议您注册要序列化的类,这样类名就不需要包含在序列化数据中。
但在类层次结构中,实际的实现类可能并不明显。例如,如果我有一个包含 Vector 对象的 Spark 数据集,则这些对象的具体类可能是 DenseVector 或 SparseVector。
当我在 Kryo 注册课程时,我应该:
- 根据数据集的声明类型(矢量(注册类
- 注册具体类(DenseVector 和 SparseVector(
- 以上所有,以防万一?
奖励问题:如果 Vector 在元组或案例类中显示为字段,您是否还需要注册产品(例如 Tuple2[Vector, Int](?
主要问题的答案
答案是...第2:) 号换句话说:
- 您只需要注册具体类,并且
- 您需要注册可能遇到的每个具体类1.
不幸的是,我现在没有文档参考来支持这一点(我从经验中知道(。
1但是,有一种特殊情况,您只能注册一个abstract
类以进行序列化/反序列化(尽管不是为了Kryo.copy()
(。这种情况是:
- 您的序列化对于所有子类都是相同的,并且
- 在反序列化期间,您可以根据数据决定返回哪个子类。
看看马丁·格罗茨克(Martin Grotzke(的ImmutableListSerializer
。在registerSerializers
方法中,他只注册ImmutableList
类以进行序列化/反序列化,因为:
- 序列化是相同的,并且
- 在反序列化期间,
ImmutableList.copyOf()
负责返回正确的子类。
奖金问题的答案
如果Vector
出现在元组或案例类中,则需要注册相应的类(例如Tuple2
(。
请注意,只要您使用Kryo.writeClassAndObject
进行序列化,泛型类型在这里无关紧要(例如ImmutableListSerializer
扩展Serializer<ImmutableList<Object>>
(。