Spark kyro Serialization

序列化在分布式系统中扮演着重要的角色,优化Spark程序时,首当其冲的就是对序列化方式的优化。Spark为使用者提供两种序列化方式:

Java serialization: 默认的序列化方式。

Kryo serialization: 相较于 Java serialization 的方式,速度更快,空间占用更小,但并不支持所有的序列化格式,同时使用的时候需要注册class。spark-sql中默认使用的是kyro的序列化方式。

下文将会讲解kryo的使用方式并对比性能。

配置

可以在spark-default.conf设置全局参数,也可以代码中初始化时对SparkConf设置 conf.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer") ,该参数会同时作用于机器之间数据的shuffle操作以及序列化rdd到磁盘,内存。

Spark不将Kyro设置成默认的序列化方式是因为它需要对类进行注册,官方强烈建议在一些网络数据传输很大的应用中使用kyro序列化。

val conf = new SparkConf()
conf.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer")
conf.registerKryoClasses(Array(classOf[MyClass1],classOf[MyClass2]))
val sc = new SparkContext(conf)

如果你要序列化的对象比较大,可以增加参数spark.kryoserializer.buffer所设置的值。

如果你没有注册需要序列化的class,Kyro依然可以照常工作,但会存储每个对象的全类名(full class name),这样的使用方式往往比默认的 Java serialization 还要浪费更多的空间。

可以设置 spark.kryo.registrationRequired 参数为 true,使用kyro时如果在应用中有类没有进行注册则会报错:

这里写图片描述

如上这个错误需要添加

sparkConf.registerKryoClasses(
    Array(classOf[scala.collection.mutable.WrappedArray.ofRef[_]],
    classOf[MyClass]))

下面的 demo 将会演示不同方式的序列化对空间占用的情况。

DEMO

case class Info(name: String ,age: Int,gender: String,addr: String)

object KyroTest {
  def main(args: Array[String]) {

  val conf = new SparkConf().setMaster("local[2]").setAppName("KyroTest")
      conf.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer")
      conf.registerKryoClasses(Array(classOf[Info]))
  val sc = new SparkContext(conf)

  val arr = new ArrayBuffer[Info]()

  val nameArr = Array[String]("lsw","yyy","lss")
  val genderArr = Array[String]("male","female")
  val addressArr = Array[String]("beijing","shanghai","shengzhen","wenzhou","hangzhou")

  for(i <- 1 to 1000000){
    val name = nameArr(Random.nextInt(3))
    val age = Random.nextInt(100)
    val gender = genderArr(Random.nextInt(2))
    val address = addressArr(Random.nextInt(5))
    arr.+=(Info(name,age,gender,address))
    }

  val rdd = sc.parallelize(arr)

  //序列化的方式将rdd存到内存
  rdd.persist(StorageLevel.MEMORY_ONLY_SER)
  rdd.count()
  }
}

结果

可以在web ui中看到缓存的rdd大小:

这里写图片描述

序列化方式是否注册空间占用
kyro21.1 MB
kyro38.3 MB
Java25.1 MB
<think>嗯,用户想了解Kyro的工作原理,特别是数据处理框架方面的内容。首先,我需要回忆一下Kyro相关的知识。根据引用[1],Kyro是一个序列化框架,用于大数据组件如Hive和Storm中,性能优越但不支持跨语言。引用[4]提到它用于Java的序列化机制,可能和动态代理、并发有关。用户的问题可能涉及Kyro如何高效处理数据,以及它在框架中的应用。 首先,序列化的核心是将对象转换为字节流,反之亦然。Kyro强调高性能,所以需要知道它是如何优化这一过程的。可能涉及对象图的处理、缓存机制、避免反射等。引用中提到不支持跨语言,说明Kyro可能依赖Java特定特性,比如直接内存访问或特定优化。 然后,数据处理框架方面,Kyro在大数据组件中的应用,比如Hive和Storm,需要处理大量数据的序列化。高效的数据交换是关键,可能Kyro在序列化速度和内存使用上有优势。可能使用了预先注册类型、复用对象等技术来减少开销。 另外,用户可能想知道Kyro与其他框架如Protobuf、Hessian的区别。比如Protobuf支持跨语言但需要IDL,而Kyro不需要但局限于Java。需要比较这些特点。 还要注意引用中提到的Kryo在dubbo中的应用,说明它在RPC场景下的使用。序列化在远程调用中非常重要,影响传输效率和延迟。Kyro的高性能可能在这里发挥作用。 需要确保回答覆盖工作原理的关键点:对象图处理、类型注册、字节码生成、缓存机制。然后数据处理框架部分,结合Hive、Storm的例子,说明高效序列化如何提升整体性能。可能还要提到局限性,比如不支持跨语言,需要业务逻辑处理脏读问题,如引用[2]提到的saga的事务隔离问题,但这里可能不直接相关,但要注意是否需要提及。 最后,生成相关问题时要围绕Kyro的机制、应用场景、与其他框架对比、优化方法等。确保问题有针对性,帮助用户深入理解。</think>### Kyro 工作原理与数据处理框架 Kyro 是一种高性能的 Java 序列化框架,专注于优化序列化速度和减少数据体积。其核心设计目标是**通过减少序列化过程中的计算和内存开销**,提升分布式系统或大数据组件的数据交换效率[^1]。 --- #### 1. **Kyro 的核心机制** - **对象图处理**:Kyro 通过深度优先遍历对象图,直接操作内存中的字节流,避免了传统序列化框架(如 Java 原生序列化)的反射和递归调用开销[^4]。 - **类型注册与缓存**: - **预先注册类型**:Kyro 要求用户显式注册需要序列化的类,以此生成高效的序列化器(如 `Kryo#register(Class)`),避免运行时动态解析类的元数据。 - **缓存序列化器**:对已注册的类,Kyro 会缓存其序列化器,减少重复初始化的性能损耗。 - **字节码生成**:Kyro 使用 ASM 库动态生成字节码,为每个注册类定制高效的序列化逻辑,例如直接操作字段偏移量来读写内存。 --- #### 2. **数据处理框架中的应用** Kyro 的轻量化设计使其在大数据场景中表现优异: - **Hive/Storm 中的数据传输**:在 Hive 中,Kyro 用于 MapReduce 任务的中间数据序列化;在 Storm 中,用于 Spout 和 Bolt 之间的元组传输。 - **性能优势**: - **低延迟**:直接内存操作和类型预注册减少了序列化耗时。 - **高压缩比**:Kyro 生成的二进制数据体积小,适合网络传输。 - **局限性**:不支持跨语言(如 Protobuf 的 IDL 机制),仅适用于 Java 生态。 --- #### 3. **对比其他序列化框架** | 框架 | 性能 | 跨语言 | 数据体积 | 典型场景 | |-----------|------|--------|----------|------------------------| | Kyro | 高 | 否 | 小 | 大数据组件、Java RPC | | Protobuf | 中 | 是 | 极小 | 微服务、跨语言通信 | | Hessian | 低 | 是 | 较大 | 传统 Web 服务 | ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值