Common:序列化

序列化(Serializing)就是将int、long、array、object等我们能看懂的编程对象转化为机器能看懂的字节流的过程,相对应的就是反序列化(Deserializing)。对象的序列化用于将对象编码成一个字节流,以及从字节流中重新构建对象。

序列化有三种主要的用途:

A、作为一种持久化格式:一个对象被序列化以后,它的编码可以被存储到磁盘上,供以后反序列化用。

B、作为一种通信数据格式:序列化结果可以从一个正在运行的虚拟机,通过网络被传播到另一个虚拟机上。

C、作为一种拷贝、克隆机制:将对象序列化到内存的缓冲区中,然后通过反序列化,可以得到一个对已存对象进行深拷贝的新对象。

在分布式数据处理中,主要使用上面提到的前两种功能。


1 Java内建序列化机制

Java序列化机制将对象转换为连续的byte数据,这些数据可以在日后还原为原先的对象状态,该机制还能自动处理不同操作系统的差异(也就是跨平台)。

Java中使一个类的实例可被序列化很简单,只需要implements Serializable这个空接口即可。

序列化主要应用在与I/O相关的一些操作上,实现是通过一对输入/输出流来实现的。如果想对某个对象执行序列化动作,可以在某种OutputStream对象的基础上创建一个对象流ObjectOutputStream对象,然后调用writeObject()就可达到目的。

输入过程类似,将InputStream包装在ObjectInputStream中并调用readObject(),该方法返回一个指向向上转型后的Object的引用,通过向下转型,就可以得到正确结果。

对象的类、类签名、类的所有非暂态和非静态成员的值,以及它所有的父类都要被写入。

A,序列化机制会自动访问对象的父类,以保证对象内容的一致性

B,不仅存储对象在内存中的原始数据,还会追踪通过该对象可以到达的其他对象的内部数据,并描述所有这些对象是如何被链接起来的。

C,不会重复保存对象的序列化结果(会引用同一个)


但是,序列化后保存了大量的与类相关的附加信息,导致序列化结果膨胀。对于需要处理和保存大规模数据的Hadoop来说,这很明显是不能容忍的。


2 Hadoop序列化机制

对比:

A,Java序列化机制在对象流ObjectOutputStream对象上调用writeObject()方法。反序列化过程会不断创建新的对象。

B,Hadoop序列化机制通过调用对象的write()方法(它带有一个类型为DataOutput的参数),将对象序列化到流中。反序列化通过对象的readFields(),从流中读取数据。反序列化过程中,用户可以复用对象,减少了Java对象的分配和回收,提高了应用效率。


处理大规模数据的Hadoop平台,序列化机制有如下特征:

A,紧凑:带宽是集群中最稀缺的资源,一个紧凑的序列化机制可以充分利用数据中心的带宽。

B,快速:在进程间通信时(包括MapReduce过程中涉及的数据交互),会大量使用序列化机制,因此必须尽量减少序列化和反序列化的开销。

C,可扩展:随着系统的发展,系统间通信的协议会升级,类的定义会发生变化,序列化机制需要支持这些升级变化。

D,互操作:可以支持不同开发语言间的通信,如C++和Java间的通信。这样的通信,可以通过文件或者后面介绍的IPC机制实现。


2.1 Hadoop Writable机制

Hadoop引入Writable接口,所有可序列化对象都必须实现该接口。该接口包含两个方法write(DataOutput out)、readFields(DataInput in)。write()方法将对象状态写入二进制的DataOutput中,readFields()方法从DataInput流中读取状态完成。Writable机制紧凑、快速,但不容易扩展到非Java语言中。


其他几个重要接口

WritableComparable,提供类型比较的能力,这对MapReduce至关重要。ByteWritable、IntWritable、DoubleWritable等Java基本类型对应的Writable类型都继承自WritableComparable。

RawComparator,提供高效比较能力,允许执行者比较流中读取的未被反序列化为对象的记录,从而省去了创建对象的所有开销。


①.基本数据类型,Hadoop使用Writable对基本数据类型进行了封装,封装前后对比如下表:

布尔值boolean字节型byte整形int长整型long双精度浮点型double
BooleanWritableByteWritableIntWritableLongWritableDoubleWritable

基本数据类型Int的Writable封装的部分源代码如下:
public class IntWritable implements WritableComparable {
  private int value;
  ......

  /** Set the value of this IntWritable. */
  public void set(int value) { this.value = value; }

  /** Return the value of this IntWritable. */
  public int get() { return value; }

  public void readFields(DataInput in) throws IOException {
    value = in.readInt();
  }

  public void write(DataOutput out) throws IOException {
    out.writeInt(value);
  }
  ......
}

②.对象数据类型,对象Object的封装ObjectWritable,适用于字段需要使用多种类型的情况。

ObjectWritable可应用于Hadoop远程过程调用中参数的序列化和反序列化;另一个典型应用是在需要序列化不同类型的对象到某一个字段。

ObjectWritable的write()方法调用的是静态方法writeObject(),该方法可以往Dataoutput接口中写入各种Java对象。在处理逻辑中,需要分别处理Java基本数据类型、Java数组、null、字符串String、枚举和Writable的子类6种情况。
ObjectWritable的readFields()方法调用的是静态方法readObject()方法,该方法依赖于WritableFactories类,该类根据输入的类型查找对应的WritableFactory工厂对象,然后创建相应的对象用于接收读出来的信息。


2.2 Hadoop序列化框架

除了刚才说过的Java序列化机制和Hadoop使用的Writable机制,还有其他流行的序列化框架:

A,Hadoop Avro是一个数据序列化系统,用于支持大批量数据交换的应用。主要特点:支持二进制序列化方式,可以便捷、快速地处理大量数据;动态语言友好,Avro提供的机制使动态语言可以方便地处理Avro数据。

B,Apache Thrift是一个可伸缩、跨语言的服务开发框架,由Facebook贡献给开源社区,是Facebook的核心框架之一。基于Thrift的跨平台能力封装的Hadoop文件系统Thrift API,提供了不同开发语言开发的系统访问HDFS的能力。

C,Google Protocol Buffer是Google内部的混合语言数据标准,提供了一种轻便高效的结构化数据存储格式。目前,Protocol Buffers提供了C++,Java,Python三种语言的API,广泛应用于Google内部的通信协议、数据存储等领域。

Hadoop提供了一个简单的序列化框架API,用于集成各种序列化实现,该框架由Serialization实现。Serialization是一个接口,使用抽象工厂的设计模式,提供一系列和序列化相关并相互依赖对象的接口。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值