在 Spark 中使用数据集时,我们需要指定用于序列化和反序列化对象的编码器。我们可以选择 使用Encoders.bean(Class<T>)
或Encoders.kryo(Class<T>)
.
它们有何不同,使用一种与另一种的性能影响是什么?
出于多种原因,始终建议使用 Kryo 序列化到 Java 序列化。其中一些在下面。
- Kryo Serialization 比 Java Serialization 更快。
- Kryo 序列化使用较少的内存占用,尤其是在您可能需要
Cache()
和Persist()
的情况下。这在像Shuffling
这样的阶段非常有帮助。 - 尽管 Kryo 支持缓存和随机播放,但在持久化到磁盘期间不受支持。
- RDD上的
saveAsObjectFile
和SparkContext
上的objectFile
方法仅支持Java序列化。 - 在数据集中处理的自定义数据类型越多,处理它们就越复杂。因此,通常最佳做法是使用像 Kryo 这样的统一序列化。 众所周知,Java的序列化
- 框架效率低下,消耗了太多的CPU,RAM和大小,无法成为合适的大规模序列化格式。
- Java 序列化需要在序列化对象时存储完全限定的类名。但是,Kryo 允许您通过保存/注册类来避免这种情况
sparkConf.registerKryoClasses(Array( classOf[A], classOf[B], ...))
或sparkConf.set("spark.kryo.registrator", "MyKryoRegistrator")
.这样可以节省大量空间并避免不必要的元数据。
bean()
和javaSerialization()
之间的区别在于 javaSerialization 使用泛型 java 序列化序列化类型T
的对象。此编码器将T
映射到单字节数组(二进制(字段。其中 as bean 为 Java Bean 创建了一个类型T
的编码器。它们都使用Java序列化,唯一的区别是它们如何将对象表示为字节。
引用文档
JavaSerialization效率极低,只能用作 最后的手段。