天天看点

Hadoop2源码分析-序列化篇1.概述2.序列化的由来3.Hadoop序列化依赖图详解4.Writable常用实现类5.总结6.结束语

  上一篇我们了解了mapreduce的相关流程,包含mapreduce v2的重构思路,新的设计架构,与mapreduce v1的区别等内容,今天我们在来学习下在hadoop v2中的序列化的相关内容,其目录如下所示:

序列化的由来

hadoop序列化依赖图详解

writable常用实现类

  下面,我们开始学习今天的内容。

  我们知道java语言对序列化提供了非常友好的支持,在定义一个类时,如果我们需要序列化一个类,只需要实现该类的序列化接口即可。场景:让一个appinfo类能够被序列化,代码如下所示:

 这么定义,不需要其他的操作,java会自动的处理各种对象关系。虽然,java的序列化接口易于实现且内建支持,同样,它的不足之处也是暴露无

遗,它占用空间过大,额外的开销导致速度降低。这些缺点对于hadoop来说是不合适的,导致hadoop没有采用java自身的序列化机制,而是

hadoop自己开发了一套适合自己的序列化机制。

  由于 hadoop 的 mapreduce 和 hdfs

都有通信的需求,需要对通信的对象进行序列化。而且,hadoop本身需要序列化速度要快,体积要小,占用带宽低等要求。因此,了解hadoop的序列化

过程是很有必要的,下面我们对hadoop的序列化内容做进一步学习研究。

  注:本文不对java的serializable接口做详细赘述,若需了解 ,请参考官方文档:http://docs.oracle.com/javase/7/docs/api/java/io/serializable.html

  在hadoop的序列化机制中,org.apache.hadoop.io 中定义了大量的可序列化对象,他们都实现了 writable 接口,writable接口中有两个方法,如下所示:

write:将对象写入字节流。

readfields:从字节流中解析出对象。

  writeable源码如下所示:

 下面我们来看看hadoop序列化的依赖图关系,如下图所示:

Hadoop2源码分析-序列化篇1.概述2.序列化的由来3.Hadoop序列化依赖图详解4.Writable常用实现类5.总结6.结束语

  从上图我们可以看出,writablecomparable接口同时继承了writable和comparable接口。

  writablecomparable源码如下所示:

  接着我们再来看看comparable的源码,代码如下所示:

  通过源码的阅读,我们可以发现,java的api提供的comparable接口,它只有一个方法,就是compareto,该方法用于比较两个对象。

  上图中列举了hadoop序列化接口中的所有类型,这里我们主要研究一些常用的实现类,如intwriteable,text,longwriteable等。

  首先我们来看看intwriteable和longwriteable的源码,具体代码如下所示:

intwriteablea

longwritable

<b></b>

  从源码intwritable和longwriteable中可以看到,两个类中都包含内部类comparator,该类的作用是用来支持在没

有反序列化的情况下直接对数据进行处理。源码中的compare(byte[] b1, int s1, int l1, byte[] b2, int

s2, int l2)方法不需要创建intwritable对象,效率比compareto(object o)高。

text

  text的源码大约有670多行,这里就不贴了,若大家要阅读详细的text源码,请在hadoop的org.apache.hadoop.io的包下,找到text类进行阅读,下面只截取text的部分源码,部分源码如下:

  从源码中看出,text继承类binarycomparable基类,并实现了

writablecomparable&lt;binarycomparable&gt;接口,writablecomparable在上面已赘述过了,

下面我们来分析一下binarycomparable,首先我们来查看一下binarycomparable的源码,部分源码如下所示:

  我们发现binarycomparable(实现了comparable接口)是一个抽象类,由该抽象类的子类去实现了hadoop二进制的序列化。该抽象类中有两个compareto方法,代码如下所示:

  从代码中,我们可以看出,两个compareto方法中依赖

writablecomparator的静态方法comparebytes来完成二进制数据的比较。另外,从text类的注视中可以看出,text是基于

utf-8编码的writeable类,注视内容如下所示:

  一般来说,在开发hadoop项目时,我们认为它等价于java的string类型,即java.lang.string。

  通过本篇博客的学习,我们对hadoop的序列化有了较深的认识,对intwriteable,longwriteable,text等实现类

也有所了解,这对我们在经后开发hadoop项目,编写相应的mr作业是有所帮助的。在类型的选择上,我们是可以做到心中有数的。

  这篇博客就和大家分享到这里,如果大家在研究学习的过程当中有什么问题,可以加群进行讨论或发送邮件给我,我会尽我所能为您解答,与君共勉!