系列化是干什么的?
序列化简单来说就保存对象在内存中的状态也可以说是实例化变量。这是Java提供的用来保存 Object state,一种保存对象状态的机制。只有实现了serializable接口的类的对象才能被实例化。Java中,一切都是对象,在分布式环境中经常需要将Object从这一端网络或设备传递到另一端。这就需要有一种可以在两端传输数据的协议。Java序列化机制就是为了解决这个问题而产生。
Spark为什么需要序列化?
Spark是分布式执行引擎,其核心抽象是弹性分布式数据集RDD,其代表了分布在不同节点的数据。Spark的计算是在Executor上分布式执行的,所以对象在执行中需要通过网络传输,或者持久化到本地磁盘的时候必须要经过序列化。
Spark序列化方式
分布式的程序存在着网络传输,无论是数据还是程序本身的序列化都是必不可少的。Spark自身提供两种序列化方式:
- Java序列化:这是Spark默认的序列化方式,使用Java的ObjectOutputStream框架,只要是实现了java.io.Serializable接口的类都可以,这种方式虽然通用但是性能差,占用的空间也比较大
- Kryo序列化:相比于Java序列化,Kryo更高效且序列化结果紧凑,占用空间小,但是不能序列化所有数据类型,且为更好的性能,需要在程序中注册需要序列化的类
注意:
- Kryo不作为默认的序列化方式,是因为需要显式注册自定义的类型,自Spark2.0后,对于一些简单类型的rdd(AllScalaRegistrar默认注册了一些常用的基本类型)在shuffling时内部默认使用Kryo作序列化
- 即使使用Kyro序列化,需要序列化的自定义类也要实现 Serializable接口。
Kryo的使用
在Spark中,为了更好的性能和使用更少的内存,建议使用Kryo序列化。
使用步骤:
- 初始化SparkContext时指定使用Kryo序列化
- 向Kryo注册自定义类(
registerKryoClasses->org.apache.spark.serializer.KryoSerializer.classesToRegister
)
示例:
val conf = new SparkConf().setMaster("local[*]").setAppName("Serial") // 声明序列化器为KryoSerializer .set("spark.serializer", "org.apache.spark.serializer.KryoSerializer") // 注册要序列化的自定义类型 .registerKryoClasses(Array(classOf[MyClass1],classOf[MyClass2],classOf[MyClass3])) val sc = new SparkContext(conf)
好了,今天就为大家分享到这里了。咱们下期见!
如果本文对你有帮助的话,欢迎点赞&收藏&分享,这对我继续分享&创作优质文章非常重要。感谢🙏🏻