![6416b888f1f57f3d5a2fe7f2f1224dcb.png](https://i-blog.csdnimg.cn/blog_migrate/2b2363f3aa5f4082f63d12dd73e00a67.png)
在Hadoop集群中,多节点通信是通过远程过程调用(Remote Produce Call,RPC)协议完成的。其中RPC是一个计算机通信协议,它允许一台计算机的程序调用另外一台计算机的子程序,即它将消息序列化成二进制流后发送到远程节点,远程节点接着将二进制流反序列化为原始消息。
其中序列化(Serialization)就是将结构化的对象转化为字节流,这样方便在网络上传输或者写入磁盘进行永久存储。反序列化(Deseralization)就是将字节流转回结构化对象的逆过程。它在分布式领域主要出现早进程间通信和永久存储的应用中。RPC序列化格式的四大理想属性非常重要:一.是储存格式紧凑,能够高效使用存储空间。二是快速,因而读/写数据的额外开销特别小。三是可扩展,可以透明读取老格式的数据。四是支持互操作,可以支持不同的语言(如C++,Java,Python)读/写永久存储数据。
Hadoop不论是进行HDFS存取操作还是进行MapReduce运算模型,都是将任务分散在不同的节点上进行传输,处理等操作。例如,MapReduce主要通过形式进行传输,排序,计算。Hadoop引入了org.apache.hadoop.io.Writable接口,作为所有可序列化对象必须支持的接口。HadoopWritable接口是基于DataInput和DataOutput实现序列化协议。
好处是:
1.格式统一,应用方便。
2.容错好,资源开销小
3.便于传输管理
总之,Hadoop序列化的核心思想是将节点数据以特定类型格式存储并以序列化形式进行传输,接收端再通过将序列化的数据重新转换为相应格式的原始数据格式。
1.Writable接口
Writable接口定义了两个方法:一个将其状态写到DataOutput二进制流,另外一个是从DataInput二进制流读取状态。通过Writable接口,基于DataInput和DataOutput实现简单,高效的序列化协议的可序列化对象。基于Hadoop MapReduce框架中的任何健和值类型都实现了该接口。其中write(DataOutput out)与readFields(Datainput in),其功能分别是将数据写入指定的流中和从指定的流中读取数据,在Hadoop应用该接口的规则中,也可以通过实现自己的write与readFields方法达到目的。
Hadoop自带的org.apache.hadoop.io包中有广泛的Writable类可供选择。 2.Java基本类型的Writable封装器
Writable类对于Java基本类型提供封装,但char除外(可以存储在IntWritable中)。所有的封装包含get()和set()两个方法。用于读取或存储封装的值。
表格来源于网络,侵权联系我删除 需要编码的数值如果相当小(-127和127之间),变长格式会依据当前的机器编码编号用1或2个字节进行编码。否则使用第一个字节来表示数值的正负和后跟多少个字节。
Writable存在的意义是解决集群中各节点间的数据传输问题。以往java程序中的是借用int,float等类型,将存于内存中的数据进行传递,而通过网络节点间的数据传输这种基于内存形式,不符合网络传输规则。故这些java基本类型通过Writable接口进行封装,以达到网络间数据传输的目的。
3.Text类
Text是针对UTF-8序列的Writable类。一般认为它是在Hadoop中实现了等同于java.lang.String的Writable类。由于它主要应对应用标准的UTF-8进行编码,故Text类的索引根据编码后子序列中的位置实现,并非字符串的Unicode字符,也不是javaChar的编码单元。
4.BytesWritable类
BytesWritable是对二进制数据数组的封装。可以通过它在源码中的构造方法代码查询。
它的构造方法接受是字节数组
它的序列化格式是指定所含数字字节的整数域(4个字节),后跟数据内容本身。BytesWritable是可变的,其值可以通过set()方法进行修改。BytesWritable的getBytes()方法,返回是字节组的容量,不能体现存储数据的实际大小,需要通过getLong()方法来确定BytesWritable的大小。
5.NullWritable类
NullWritable是Writable的一个特殊类型,它的序列化长度为0。但它并不从数据流中读取数据,也不写入数据,而并且充当占位符。在MapReduce中,如果不需要使用健或者值,就可以将健或者值声明为NullWritable-结果是存储常量的空值。
6.ObjectWritable类
ObjectWritable是Writable和configurable接口的实现,是对java基本类型的一个通用封装。它是Hadoop RPC中用于对方法参数和返回类型进行封装和解封装。尤其在一个字段有多个类型的时候,可以将值类型声明为ObjectWritable,将每一个类型封装在一个ObjectWritable中,但作为一个有用的类,它同样占用大量的空间 6.自定义Writable接口
Hadoop自带的Writable接口为应用在分布式存储系统间传输数据提供便利,能满足大部分需求,但在一些复杂业务中,它的一些功能尽不显尽如意。Hadoop自带框架机制非常灵活,用户可以依据自己业务需求定制Writable类型,用以完成多值的封装传递或完全控制的二进值表示和排序。 HDFS平台可以存储结构,半结构和非结构化数据,而MapReduce数据处理的计算过程中,将数据以合理格式进行存储是一件有意义的事。例如,文本类型存储,二进制数据类型格式存储等。HadoopSequenceFile类为二进制key/value对提供了一个持久的数据结构,可以存储二进制类型的文件,同时SequenceFile也可以作为小文件的容器,将若干小文件打包成一个SequenceFile类,效率较高。
1.SequenceFile提供了SequenceFile.Writer,SequenceFile.Reader和SequenceFile.Sorter类,分别用于写入,读取和排序的编程应用。
2.MapFile
MapFile继承自SequenceFile,是一个已经排序的SequenceFile。MapFile一般会生成data和index两部分。其中index作为文件的索引,记录了每一个Record的Key值和该Record在文件中的偏移位置,其中索引的间隔是通过io.map.index.interval进行设定的。在MapFile被访问时候,索引文件会被加载在内存,通过索引映射关系,可以迅速定位到指定的Record所在的文件位置,因此对于SequenceFile而言,MapFile的检索是高效率的,缺点是会消耗一部分内存来存储index数据。其中MapFile提供的Key继承的是WritableComparable接口,便于在计算机中排序,可以实现Key查找。