操作场景
spark支持两种方式的序列化:
● Java 原生序列化 JavaSerializer
● Kryo 序列化 KryoSerializer
序列化对于 Spark 应用的性能来说,具有很大的影响。在特定的数据格式的情况下,KryoSerializer 的性能可以达到 JavaSerializer 的10倍以上,而对于一些 Int 之类的基本数据类型,性能的提升微乎可微。
KryoSerializer 依赖 Twitter 的Chill库来实现,相对于 JavaSerializer, 主要的问题在于不是所有的 Java Serializable 对象都能支持,兼容性不好,所以需要手动注册类。
序列化功能用在两个地方: 序列化任务和序列化数据。 Spark任务序列化只支持 JavaSerializer,数据序列化支持 JavaSerializer 和 KryoSerializer。
操作步骤
Spark程序运行时,在 shuffle 和 RDD Cache 等过程中,会有大量的数据需要序列化,默认使用 JavaSerializer,通过配置让 KryoSerializer 作为数据序列化器来提升序列化性能。
在开发应用程序时,添加如下代码来使用 KryoSerializer 作为数据序列化器。
● 实现类注册器并手动注册类。
package com.etl.common;
import com.esotericsoftware.kryo.Kryo;
import org.apache.spark.serializer.KryoRegistrator;
public class DemoRegistrator implements KryoRegistrator {
@Override
public void registerClasses (Kryo kryo) {
//以下为示例类,需注册自定义类
kryo.register(AggrateKey.class);
kryo.register(AggrateValue.class);
}
}
可以在Spark客户端对 spark.kryo.registrationRequired 参数进行配置,设置是否需要 Kryo 注册序列化。
当参数设置为true时,如果工程中存在未被序列化的类,则会抛出异常。如果设置为 false (默认值),kryo会自动将未注册的类名写到对应的对象中。此操作会对系统性能造成影响。设置为 true 时,用户需手动注册类,针对未序列化的类,系统不会自动写入类名,而是抛出异常,相对 false,其性能要好。
● 配置 KryoSerializer 作为数据序列化器和类注册器。
val conf = new SparkConf()
conf.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer")
.set("spark.kryo.registrator", "com.etl.common.DemoRegistrator")