CodeWalk

Spark Kryo序列化详解

作者:苦行僧 · 2026-05-30 12:55

请说明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:

  1. Shuffle数据量大(Shuffle Write/Read的瓶颈在序列化)
  2. RDD持久化为MEMORY_ONLY_SER(减少内存占用)
  3. 广播变量大(Broadcast通过网络传输)
  4. 自定义类作为RDD元素类型

注意:

  • Spark 2.x+ 中Shuffle默认已使用Kryo
  • DataFrame/Dataset使用Tungsten编码器(比Kryo更高效),无需额外配置