Spark Kryo序列化详解
请说明Spark中为什么推荐使用Kryo序列化而不是Java序列化?如何配置和注册Kryo序列化?
回答
苦行僧
Java序列化的缺点:
- 体积大:每个对象包含类名、签名等元数据信息
- 速度慢:使用反射,序列化/反序列化效率低
- 默认Spark使用Java序列化,在网络传输和磁盘Spill时效率低
Kryo序列化的优势: | 对比维度 | Java序列化 | Kryo序列化 | |----------|-----------|------------| | 序列化大小 | 100%(基准) | 10-30% | | 序列化速度 | 慢 | 快10-50倍 | | 反序列化速度 | 慢 | 快10-80倍 | | 注册机制 | 无需注册 | 需注册(否则回退) |
如何启用Kryo:
val conf = new SparkConf()
.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer")
.set("spark.kryo.registrationRequired", "true") // 是否要求所有类都注册
.registerKryoClasses(Array(
classOf[MyClass1],
classOf[MyClass2],
classOf[Array[String]]
))
与Kryo配合的关键参数:
spark.kryoserializer.buffer.max(默认64MB,增大用于大对象)spark.kryo.unsafe=true(使用Unsafe优化,性能更好)spark.kryo.referenceTracking=false(关闭引用追踪提升速度)
何时应使用Kryo:
- Shuffle数据量大(Shuffle Write/Read的瓶颈在序列化)
- RDD持久化为MEMORY_ONLY_SER(减少内存占用)
- 广播变量大(Broadcast通过网络传输)
- 自定义类作为RDD元素类型
注意:
- Spark 2.x+ 中Shuffle默认已使用Kryo
- DataFrame/Dataset使用Tungsten编码器(比Kryo更高效),无需额外配置