简单聊聊Kryo serialization
来源:互联网 发布:谷歌搜索引擎优化指南 编辑:程序博客网 时间:2024/05/18 03:02
Spark默认使用Java的序列化和反序列化机制,即使用Java的ObjectOutputStream框架,支持所有继承于java.io.Serializable对象的序列化。但在Java序列化时,并没有对序列化的byte做任何处理,序列化的元素也太多了:包括开发、类描述、字段值、类的版本、元数据、字段描述和字段值等信息,造成Java序列化速度慢,序列化后的byte数组大。
因此,Spark又提供了另一种高效的序列化方法:Kryo。Kryo是一个快速高效的Java对象图形序列化框架,原生支持Java,且在Java的序列化上甚至优于Google著名的序列化框架protobuf。那,Kryo为什么那么快呢?
Kryo为了保证序列化的高效性,不会序列化对象的field描述信息,且对int和long使用变长存储。这样,序列化后的对象大小就比较小,且由于Kryo只会在第一次序列化类时才去加载类,后续直接保存了类的信息,整体的序列化速度就会提升很明显。详细研究的话,读者可以对比上述两种序列化后的byte内容。
好了,简单了解了Kryo的基本信息后,我们来看看如何在Spark中使用Kryo serialization。
Spark中使用Kryo serialization
因此,Spark又提供了另一种高效的序列化方法:Kryo。Kryo是一个快速高效的Java对象图形序列化框架,原生支持Java,且在Java的序列化上甚至优于Google著名的序列化框架protobuf。那,Kryo为什么那么快呢?
Kryo为了保证序列化的高效性,不会序列化对象的field描述信息,且对int和long使用变长存储。这样,序列化后的对象大小就比较小,且由于Kryo只会在第一次序列化类时才去加载类,后续直接保存了类的信息,整体的序列化速度就会提升很明显。详细研究的话,读者可以对比上述两种序列化后的byte内容。
好了,简单了解了Kryo的基本信息后,我们来看看如何在Spark中使用Kryo serialization。
Spark中使用Kryo serialization
如下示例,在初始化SparkContext之前,需指定使用Kryo serialization。
object KryoSparkTest { def main(args: Array[String]) { val conf = new SparkConf() conf.setMaster("local") conf.setAppName("KryoSparkTest") // 指定使用Kryo序列化 conf.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer") conf.set("spark.kryo.registrator", "com.gjl.kryotest.MyRegistrator") val sc = new SparkContext(conf) val rdd = sc.textFile("src/main/resources/hello.txt") val srcMap = rdd.map(f => { val line = f.split(",") val hello = new Hello hello.setA(line(0).toInt) hello.setId(line(1).toLong) hello.setWords(line(2)) hello }) srcMap.persist(StorageLevel.MEMORY_AND_DISK_SER) println(srcMap.count()) }}其中,MyRegistrator的定义如下:public class MyRegistrator implements KryoRegistrator { @Override public void registerClasses(Kryo kryo) { kryo.register(Hello.class); }}Hello类的定义如下:public class Hello implements Serializable { private int a; private long id; private String words; public int getA() { return a; } public void setA(int a) { this.a = a; } public long getId() { return id; } public void setId(long id) { this.id = id; } public String getWords() { return words; } public void setWords(String words) { this.words = words; }}运行KryoSparkTest,查看输出日志,如:16/04/05 10:18:13 INFO MemoryStore: Block rdd_2_0 stored as bytes in memory (estimated size 37.0 B, free 118.8 KB)如果不使用Kryo serialization,运行结果为:16/04/05 10:46:00 INFO MemoryStore: Block rdd_2_0 stored as bytes in memory (estimated size 160.0 B, free 118.9 KB)从上述运行结果中可以看出Kryo serialization的存储优势。由于hello.txt文本数比较小,仅说明问题,不做速度压测验证。Scala如何使用Kryo?Chill是Kryo serialization库的Scala扩展。为什么使用Chill,可参加官网说明: Scala classes often have a number of properties that distinguish them from usual Java classes. Often scala classes are immutable, and thus have no zero argument constructor. Secondly, object in scala is a singleton that needs to be carefully serialized. Additionally, scala classes often have synthetic (compiler generated) fields that need to be serialized, and by default Kryo does not serialize those.下面是一个简单的使用示例:object ChillTest { def main(args: Array[String]) { val src = Source.fromFile("src/main/resources/hello.txt").getLines().map(f => { val line = f.split(",") val hello = new Hello hello.setA(line(0).toInt) hello.setId(line(1).toLong) hello.setWords(line(2)) hello }).toList val instantiator = new ScalaKryoInstantiator instantiator.setRegistrationRequired(false) val kryo = instantiator.newKryo() val baos = new ByteArrayOutputStream() val output = new Output(baos, 4096) kryo.writeObject(output, src) val input = new Input(baos.toByteArray) val deser = kryo.readObject(input, classOf[List[Hello]]) assert(deser.size == 3) }}
结语
前文讲过,Kryo为了做到高效序列化,并不序列化对象的field信息,因此,在使用Kryo serialization之前要记得自己加载需要序列化的类。如果Spark中设置了Kryo序列化,但忘记注册类了,运行时会直接报错。另外,序列化类的ID信息也要合理设计,兼容版本和连续性。
另外,本文对序列化的底层技术细节没有过多涉及,也没有详细解析Kryo serialization后的数组内容和Kryo的源码,有兴趣的读者可以自行研究下。文中有陈述不完善的地方,也请批评指正,共同提高,多谢。
阅读全文
0 0
- 简单聊聊Kryo serialization
- Spark Q&A : Kryo serialization failed: Buffer overflow
- Kryo
- Serialization 简单小结
- Java 序列化--- Kryo使用简单例子
- spark解决 org.apache.spark.SparkException: Kryo serialization failed: Buffer overflow
- spark解决org.apache.spark.SparkException: Kryo serialization failed: Buffer overflow
- 简单聊聊onMeasure
- 简单聊聊Handler机制
- 简单聊聊设计
- 简单聊聊8583
- 简单聊聊CANVAS画图
- 简单聊聊 instanceof ,typeof
- 简单聊聊搜索
- serialization
- Serialization
- Serialization
- Serialization
- tplink 有良知的路由器厂商
- c语言写蛇形矩阵
- MDK4.60界面使用笔记
- Markdown学习
- 魔法阵
- 简单聊聊Kryo serialization
- BZOJ 2242: [SDOI2011]计算器
- 当你输入网址时都发生了什么(2)——TCP链接的建立
- MySQL入门--创建数据库、显示警告信息、显示数据库、显示数据库创建信息、指定字符编码集
- Applet 类
- java面试题(下)
- 1232: 评委打分
- (OK) zebra.conf
- 袁萌:60年前参加高考的亲身经历