hadoop技术内幕-序列化与压缩(一)
一、java内建序列化机制
java序列化机制将对象转换为连续的byte数据,这些数据可以在日后还原为原先的对象状态,还能自动处理不同操作系统上的差异,也不用担心字节排列次序。
java的类实例可被序列化只要在类声明中加入implements Serializable即可。Serializable接口是一个标志,不具有任何成员函数。
java的序列化会自动访问对象的父类,以保证对象内容的一致性。序列化的结果中包含了大量与类相关的信息(包括版本号、类描述信息、类的版本ID、父类等)。在这个过程中序列化输出中保存了大量的附加信息,导致序列化结果膨胀。
二、Hadoop序列化机制
hadoop序列化机制通过调用对象的write()方法,将对象序列化到流中。反序列化是通过对象的readFields(),从流中读取数据。java序列化机制中,反序列化过程会不断地创建新的对象,但在Hadoop的序列化机制的反序列化过程中,用户可以复用对象。
hadoop序列化机制特点:紧凑、快速、可扩展、互操作。java序列化机制中,java Serialization会将每个对象的类名写入输出流中,这导致了java序列化对象需要占用比原来对象更多的存储空间。同时为了减少数据量,同一个类的对象的序列化结果只输出一份元数据,并通过某种形式的引用来共享元数据。
hadoop引入了org.apache.hadoop.io.writable接口,作为所有可序列化对象必须实现的接口,Writable机制紧凑、快速。和java.io.Serializable不同,Writable接口不是一个说明性接口。此外,hadoop序列化机制中还包含另外几个重要接口:WritableComparable、RawComparator和WritableComparator。
大部分的MapReduce程序都是使用Writable键-值对作为输入和输出,但这并不是hadoop的API指定的。其它的序列化机制也能和hadoop配合,并应用于mapreduce中。除了java序列化机制和hadoop的writable机制,还流行其它序列化框架,如:hadoop avro、apache thrift和google protocol buffer。Hadoop提供了一个简单的序列化框架API,用于集成各种序列化实现,该框架由serialization实现。hadoop目前支持两个serialization实现,分别支持writable机制的WritableSerialization和支持java序列化的javaSerialization。通过javaSerialization可以在MapReduce程序中方便地使用标准的java类型,但java的Object Serialization不如Hadoop的序列化机制有效,非特殊情况不要轻易尝试。