Hadoop序列化及IPC通信机制简析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_35488412/article/details/78612228

 一、Hadoop序列化

1、简介:

什么是序列化?将对象编码成一个字节流。 反序列化:将一个字节流编码成对象。

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

  1. 作为一种持久化存储。可以把对象序列化后存储到磁盘上,供以后反序列化使用。
  2. 作为一种通信数据格式。
  3. 作为一种拷贝、克隆机制。

序列化在分布式数据处理的常用上面提到的前两种功能:持久化存储和进程间通信。

        处理大规模数据的hadoop平台,其序列化机制需要如下特征:

紧凑、快速、可扩展、互操作

       宽带是hadoop集群最稀缺的资源,紧凑的序列化机制可以充分利用数据中心的宽带。在Hadoop中,它使用自己的序列化框架Writable,它格式紧凑、速度快,但由于基于java编写且结合较为紧密,所以缺点是很难用Java以外的语言来扩展。 

2、和java序列化机制区别:

  • 和Java的序列化机制不同(在对象ObjectOutputStream对象上调用writeObject()方法),Hadoop的序列化机制通过调用对象的write()方法(它带有一个类型为DataOutput的参数),将序列化到流中。反序列化则通过调用对象的readFields(),从流中读取数据。
  • 由于Java本身提供的序列化机制,在将对象序列化的时候会保持大量的附加信息,以至于序列化以后的对象过于庞大,对于需要保持和处理大规模数据的Hadoop来说,需要一个新的序列化机制。
  • java序列化机制中,反序列化会不断的创建新的对象,但在hadoop的序列化机制的反序列化过程中,用户可以复用对象。

3、Hadoop Writable框架解析 


      序列化和反序列化只是在对象和字节转换的过程中定义了一个数据格式传输协议,只要在序列化和反序列化过程中,严格遵守这个数据格式传输协议就能成功的转换,当然也可以自行完全实现hadoop序列化框架,像avro框架一样。

Writable.java

@InterfaceAudience.Public
@InterfaceStability.Stable
public interface Writable {
  /** 
   * 序列化一个对象,将一个对象按照某个数据传输格式写入到out流中
   * Serialize the fields of this object to <code>out</code>.
   * @throws IOException
   */
  void write(DataOutput out) throws IOException;

  /** 
   * 反序列化,从in流中读入字节,按照某个数据传输格式读出到一个对象中
   * Deserialize the fields of this object from <code>in</code>.  
   * @throws IOException
   */
  void readFields(DataInput in) throws IOException;
}

Comparable.java

public interface Comparable<T> {

    /**
     * 比较对象,这个在mapreduce中对key的对象进行比较
     * Compares this object with the specified object for order.  Returns a
     * negative integer, zero, or a positive integer as this object is less
     * than, equal to, or greater than the specified object.
     */
    public int compareTo(T o);
}

RawComparator.java

@InterfaceAudience.Public
@InterfaceStability.Stable
public interface RawComparator<T> extends Comparator<T> {

  /**
   * 在mapreduce,spill过程中,当spill的缓存达到一个值时,会将key-value写入到本地磁盘,并在此过程中sort和patition,如果实现了该接口,就可以直接以序列化的字节的状态比较key,而不需要再临时反序列化成对象再比较,这样提高了效率节省了时间。
   * Compare two objects in binary.
   * @param b1 The first byte array.
   * @param s1 The position index in b1. The object under comparison's starting index.
   * @param l1 The length of the object in b1.
   * @param b2 The second byte array.
   * @param s2 The position index in b2. The object under comparison's starting index.
   * @param l2 The length of the object under comparison in b2.
   * @return An integer result of the comparison.
   */
  public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2);

}

4、hadoop序列化框架:

       大多MapReduce程序都使用Writable键-值对作为输入和输出,但并不是hadoop的api指定的,其他序列化机制能和Hadoop配合,并应用于MapReduce中。

除了java序列化机制和hadoop使用的writable机制,还支持流行其他的序列化框架,如hadoop Avro、Apache Thrift 和Google Protocol Buffer。

Avro是一个数据序列化系统,用于支持大批量数据交换的应用。

Thrift是一个可伸缩的、跨语言的服务开发框架,提供了不同开发语言开发的系统访问HDFS的能力。

Google Protocol Buffer是谷歌内部的混合语言数据标准,提供了一种轻便高效的结构化数据存储格式。

序列化机制在RPC中的应用:

RPCHadoop中,系统中多个节点上进程间的通信是通过远程过程调用remote procedure call, RPC)实现的。RPC将消息序列化成二进制流后发送到远程节点,远程节点接着将二进制流饭序列化为原始消息。

通常情况下,RPC序列化格式许紧凑、快速、可扩展、和互操作!紧凑的格式能够使我们充分利用数据中心中最稀缺的资源——网络带宽。

 序列化广泛应用于分布式数据处理中,是交换数据必备的能力。hadoop没有使用java内建的序列化机制,而是引入了紧凑、快速、轻便和可扩展的Writable接口。Writable接口通过write()和readFields()方法声明了序列化和反序列化的功能。

 

二、hadoop压缩

压缩:一般计算机处理的数据都存在一些冗余度,同时数据中间,尤其是相邻数据间存在着相关性,所以可以通过一些有别于原始编码的特殊编码方式来保存数据,是数据占用的存储空间比较小,这个过 程一般叫压缩。

hadoop 中有两个地方要使用到压缩:

第一:在HDFS上存储数据文件,压缩之后有体积小利于存储;

第二:集群间的通信需要压缩数据,这样可以提高网络带宽的利用率。例如map到reduce阶段的数据交换等情景。

如果用MapReduce算法处理压缩文件,要求压缩算法能支持文件分割,因为MapReduce的过程需要将文件分割成多个切片。如果压缩算法不支持文件分割,那就不能做切片了。

       Java中(hadoop基于java编写),一切输入输出都用流的方式进行,可以读取字节序列的对象叫输入流,文件,网络连接,内存区域都可以是输入流。一个可以写入字节序列的对象叫输出流。文件,网络连接,内存区域都可以是输出流。

  假设hadoop的输入流是A, 输出流是B. 做压缩的话,先选择压缩算法,然后根据压缩算法创建相应的压缩器,然后用压缩器和输出流B创建压缩输出流C,最后将数据从输入流A复制到压缩输出流C即可进行压缩并输出结果。如果是解压缩,先选择解压缩算法,然后根据解压缩算法创建相应的解压缩器,然后用解压缩器和输入流A创建压缩输入流C,最后将数据从输入流C复制到输出流B即可进行解压缩并输出结果。

       hadoop必须支持多种压缩算法,如何灵活地支持这些算法呢?hadoop实现了压缩框架,包括编码/解码器及其工厂、压缩器/解压器、压缩流/解压缩流三种组件,它们互相配合满足了用户对压缩功能的需求。

Hadoop IPC远程过程调用

RPC原理:

         RPC就是允许程序调用位于其他机器上的过程(也可以是同一台机器的不同进程)。当机器A调用机器B上的进程时,A的调用进程挂起等待B返回结果,而B的进程开始执行。调用者向B传递参数,B处理完后再把结果传给A。A是RPC客户,B是RPC服务器。

         RPC 的主要功能目标是让构建分布式计算(应用)更容易,在提供强大的远程调用能力时不损失本地调用的语义简洁性。随着RPC的发展,出现了大量相关技术如XML-RPC、JSON-RPC、CORBA和RMI等,我们重点关注hadoop IPC,属于RPC的一种比较理想的实现。

比如服务器A、B,一个应用部署在A服务器上,相应调用B服务器上应用提供的函数\方法,由于不在一个内存空间,不能直接调用,需要通过网络来表达调用的语义和传达调用的数据。1.首先解决通讯问题,建立TCP连接,解决寻址问题。2.通过序列化利用二进制传输。3.收到数据后反序列化,恢复内存中的表达方式,找到对应方法后执行得到返回值。

Java RMI

        Java 远程方法调用(Remote Method Invocation,RMI)是java的一个核心API和类库,允许一个java虚拟机上允许的java程序调用不同虚拟机上运行的对象中的方法,即使这两个虚拟机运行于物理隔离的不同主机上。在某种程度上,RMI可以看成RPC的java升级版。

Hadoop IPC

       Hadoop中的远程过程调用,实现了一套自己独有的节点间通信机制,理由和hadoop使用writable形式的序列化机制类似,有效的IPC(Inter-Process Communication,进程间通信)对于hadoop来说是至关重要。RMI的可控性不够灵活,其次数据序列化格式不够精简,Hadoop需要精准控制进程间通信中比如连接、超时、缓存等通信细节。而Java RMI达不到这些需求,通过结合数据输出流和数据输入流的Writable的序列化机制,构建一个简洁的、低消耗的远程过程调用机制。

IPC主要技术元素

  1. 序列化对象(数据传输的核心)              
  2. 反射
  3. 动态代理                               
  4. Socket传输

原理:

       客户端调用远程方法时,通过动态代理运用反射机制将所需参数以及方法等封装成序列化对象通过Socket传输给服务端,在没有接受到返回值时一直Wait。服务端获取到序列化对象后通过反射机制调用指定的方法得到返回值,然后将返回值传输给客户端。客户端接受到返回值后被Notify。

猜你喜欢

转载自blog.csdn.net/qq_35488412/article/details/78612228