`

Hadoop学习分享----Hadoop I/O序列化

 
阅读更多

一、关于序列化:

      序列化,可以存储“活的”( 只生存在内存里,关机断电就没有了,一般只能由本地的进程使用,而不能被发送到网络上的另外一台计算机)对象,可以将“活的”对象发送到远程计算机。
      而把“活的”对象序列化,就是把“活的”对象转化成一串字节,而“反序列化”,就是从一串字节里解析出“活的”对象。于是,如果想把“活的”对象存储到文件,存储这串字节即可,如果想把“活的”对象发送到远程主机,发送这串字节即可,需要对象的时候,做一下反序列化,就能将对象“复活”了。
      将对象序列化存储到文件,术语又叫“持久化”。将对象序列化发送到远程计算机,术语又叫“数据通信”。
   
     序列化的目的:

  • 进程间的通信
  • 数据持久性存储

二、HADOOP的序列化:

hadoop在节点间的内部通讯使用的是RPC,RPC协议把消息翻译成二进制字节流发送到远程节点,远程节点再通过反序列化把二进制流转成原始的信息。RPC的序列化需要实现以下几点:

1.压缩,可以起到压缩的效果,占用的宽带资源要小。

2.快速,内部进程为分布式系统构建了高速链路,因此在序列化和反序列化间必须是快速的,不能让传输速度成为瓶颈。

3.可扩展的,新的服务端为新的客户端增加了一个参数,老客户端照样可以使用。

4.兼容性好,可以支持多个语言的客户端

在hadoop中,序列化处于核心地位。因为无论是存储文件还是在计算中传输数据,都需要执行序列化的过程。序列化和反序列化的速度、序列化后的数据大小都会影响数据传输的速度,以致影响计算的效率。

为什么不使用java序列化?

  • java的序列化机制在每个类的对象第一次出现的时候保存了每个类的信息,比如类名,第二次出现的类对象会有一个类的reference,导致空间的浪费。
  • 有成千上万(打个比方,不止这么多)的对象要反序列化, 而java序列化机制不能复用对象, java反序列化的时候, 每次要构造出新的对象,在hadoop的序列化机制中, 反序列化的对象是可以复用的。
  • java序列化不够灵活,hadoop自己写序列化很容易,而java不是。

下面介绍下Hadoop的序列化机制:

Writable类:

Writable是Hadoop的核心,Hadoop通过它来定义了Hadoop中基本的数据类型及其操作。Writable类也就是org.apache.hadoop.io.Writable接口,Hadoop的所有可序列化对象都必须实现这个接口,Hadoop中的key和value必须是实现了Writable接口的对象,以支持在MapReduce任务中的序列化和反序列化。Writable接口里有两个方法,一个是write方法,将对象写入字节流,另一个是readFields方法,从字节流解析出对象。下面是Writable类得层次结构:

 

从上图中,我们可以看到如BooleanWritable、ByteWritable等类不是直接继承自Writable类,而是继承自WritableComparable类,WritableComparable是Hadoop中非常重要的接口类,WritableComparable接口是可序列化并且可比较的接口,MapReduce中所有的key值类型都必须实现这个接口,既然是可序列化的那就必须得实现readFiels()和write()这两个序列化和反序列化函数,既然也是可比较的那就必须得实现compareTo()函数,该函数即是比较和排序规则的实现,这样MR中的key值就既能可序列化又是可比较的,那么Hadoop为什么中的MR的Key值为什么是可比较的?Hadoop又是如何实现比较器的呢?带着这两个问题,接下来介绍下Hadoop的比较器。

<一>、Hadoop的比较器

大家都知道,MapReduce在执行时,Reducer(执行reduce任务的机器)会收集相同KEY值的 key/value对,并且在reduce之前会有一个排序过程,排序是MapReduce的核心技术,尽管应用程序本身不需要对数据排序,但可以使用MapReduce的排序功能来组织数据。WritableComparable的比较器是由WritableComparator来实现的,MR键值的比较都是通过对WritableComparator类型来进行比较,类图如下:

从类图中,我们也可以看到WritableComparator实现了RawComparator接口类,RawComparator类定义了对未反序列化对象的读取,可直接用于序列化字节间的比较的方法,这样做有什么好处?大家都知道Hadoop多个节点上的进程间通信是通过远程过程调用RPC实现的,而RPC协议会将消息序列化为二进制流后再发送到远程节点,远程节点接收到二进制流后再反序列化为原始消息,如果对序列化的二进制流直接比较则会提高效率,避免了创建对象的开销。

 RawComparator接口的唯一方法是int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2),其中b1为第一个对象所在的字节数组,s1为该对象在b1中的起始位置,l1为对象在b1中的长度,b2为第一个对象所在的字节数组,s2为该对象在b2中的起始位置,l2为对象在b2中的长度。WritableComparator类是RawComparator的子类,用于比较实现了WritableComparable接口的对象。基本的实现是按照自然顺序进行比较,若想按照其它顺序比较,比如逆序,可以继承该类并覆盖compare(WritableComparable,WritableComparable)来实现定制的比较器。这是因为在针对字节的compare方法中,最终调用了compare(WritableComparable,WritableComparable)方法,因此该方法决定了按照什么方式进行比较。可以通过覆盖compare(byte[],int,int,byte[],int,int)优化比较操作,该类提供了许多静态方法以帮助该方法的优化实现。

实现代码如下:

@Override

public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {

    try {

      buffer.reset(b1, s1, l1);                   // parse key1

      key1.readFields(buffer);

   

      buffer.reset(b2, s2, l2);                   // parse key2

      key2.readFields(buffer);

     

    } catch (IOException e) {

      throw new RuntimeException(e);

    }

    return compare(key1, key2);                   // compare them

}

 

 <二>、Writable类中的基本数据类型

Writable中封装有很多JAVA的基本类,如图:

Java基本类型

Writable

布尔型(Boolean)

BooleanWritable

字节型(byte)

ByteWritable

整型(int)

IntWritable

VIntWritable

浮点型(float)

FloatWritable

长整型(long)

LongWritable

VLongWritable

双精度浮点型(double)

DoubleWritable

Hadoop还自定义了两个变长的类型,VIntWritable和VLongWritable,Hadoop对于VLong类型的处理方法的实现得比较巧妙:

具体代码如下:

上面代码的意思是如果数值比较小(在-112和127之间),那么就直接将这个数值写入数据流中。如果不是,则先用len表示字节长度与正负,并写入数据流中,然后在其后写入这个数值。比较费脑,有兴趣的同学可详细看下。

下面再介绍几个Hadoop常用的Writable类型:

(1)Text类

   Text类是针对UTF-8序列(UTF-8是UNICODE的一种变长字节字符编码,又称万国码)的Writable类,一般认为他等价与java.lang.String的Writable类。但是他和String还是有一些差异的。Text的索引是按编码后字节序列中的位置来实现的,String是按其所包含的char编码单元来索引的。看下面的例子:

            String s=String("\u0041\u00df\uu6671\ud801\uDc00");

            Text t=Text("\u0041\u00df\uu6671\ud801\uDc00");

            s.indexof("\u0041")==0            t.find("\u0041")==0

            s.indexof("\u00df")==1             t.find("\u00df")==1

            s.indexof("\u6671")==2            t.find("\u6671")==3

            s.indexof("\ud801\uDc00")==3 t.find(\ud801\uDc00")==6

            s.length()==5    s.getBytes("UTF-8").length()==10

            t.getLength()==10(1+2+3+4)

    通过字节偏移量来进行位置索引,实现对Text类的Unicode字符迭代是非常复杂的,因为不能简单的通过增加位置的索引值来实现。所以必先将Text对象转化为java.nio.BytesBuffer对象,然后利用缓冲区对Text对象反复调用bytesToCodePoint()静态方法,该方法能获取下一代码的位置。

    由于Text类不像java.lang.String类那样有丰富的字符串操作API,所以在一些情况下为了方便处理,需要将Text类转化为String类,这一过程通过toString来实现。
(2)ByteWritable类,二进制数据数组的封装,它的序列化格式为一个用于指定后面数据字节数的整数域(4字节),后跟字节本身。

(3)NullWritabe,是Writable的一个特殊类型,它的序列化长度为0,类似于null。

(4)ObjectWritable类,是对java基本类型(String,enum,Writable,null或这些类型组成的数组)的一个通用封装。

(5)Writable集合类,共有4个集合类,其中ArrayWritable是对Writable的数组的实现,TwoDArrayWritable是对Writable的二维数组的实现,MapWritable是对Map的实现,SortedMapWritable是对SortedMap的实现。

(6)定制的Writable类,我们可以根据自己的需求构造自己的Writable类,可以根据需要控制二进制表示和排序顺序,由于Writable是MapReduce数据路径的核心,所以调整二进制表示能对性能残生显著效果。

 
三、总结

    Hadoop的序列化机制非常简单直接,并不像JAVA的序列化那样面面俱到,这样可以使数据更加紧凑,同时也可以加快序列化和反序列化的速度。

 

分享到:
评论

相关推荐

    Hadoop 3.x(MapReduce)----【Hadoop 序列化】---- 代码

    Hadoop 3.x(MapReduce)----【Hadoop 序列化】---- 代码 Hadoop 3.x(MapReduce)----【Hadoop 序列化】---- 代码 Hadoop 3.x(MapReduce)----【Hadoop 序列化】---- 代码 Hadoop 3.x(MapReduce)----【Hadoop ...

    java-Hadoop序列化

     Hadoop序列化的特点  Hadoop的序列化格式:Writable  序列化格式特点:  紧凑:高效使用存储空间。  快速:读写数据的额外开销小  可扩展:可透明地读取老格式的数据  互操作:支持多语言的交互

    Apache Hadoop---Avro.docx

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

    Hadoop序列化机制

    NULL 博文链接:https://wmwork2010.iteye.com/blog/629320

    Hadoop大数据零基础实战培训教程- Avro数据序列化系统(1)

    Hadoop是什么,为什么要学习Hadoop? Hadoop是一个分布式系统基础架构,由Apache基金会开发。用户可以在不了解分布式底层细节的情况下,开发分布式程序。充分利用集群的威力高速运算和存储。Hadoop实现了一个分布式...

    新版Hadoop视频教程 段海涛老师Hadoop八天完全攻克Hadoop视频教程 Hadoop开发

    02-hadoop中的序列化机制.avi 03-流量求和mr程序开发.avi 04-hadoop的自定义排序实现.avi 05-mr程序中自定义分组的实现.avi 06-shuffle机制.avi 07-mr程序的组件全貌.avi 08-textinputformat对切片规划的源码...

    Hadoop权威指南 中文版

     ·熟悉hadoop的数据和ilo构件,用于压缩、数据集成、序列化和持久处理  ·洞悉编~mapreduce实际应用时的常见陷阱和高级特性  ·设计、构建和管理一个专用的hadoop集群或在云上运行hadoop  ·使用高级查询语言...

    Hadoop大数据零基础实战培训教程_Avro数据序列化系统.rar

    Hadoop是一个分布式系统基础架构,由Apache基金会开发。用户可以在不了解分布式底层细节的情况下,开发分布式程序。充分利用集群的威力高速运算和存储。Hadoop实现了一个分布式文件系统(Hadoop Distributed File ...

    HADOOP硬实战2

    在关键问题领域对基础概念和实战方法做了权衡,例如导入导出、序列化,以及LZO压缩。你将会学习到每个技术的细节,以及当遇到一个具体问题时能够给出对应的解决方案。本书提供了结构良好且易于理解的例子,可用于...

    hadoop段海涛老师八天实战视频

    第一天 hadoop的基本概念 伪分布式hadoop集群安装 hdfs mapreduce 演示 ... 02-hadoop中的序列化机制.avi 03-流量求和mr程序开发.avi 04-hadoop的自定义排序实现.avi 05-mr程序中自定义分组的实现.avi

    Hadoop大数据零基础实战培训教程-Avro数据序列化系统(2)

    Hadoop是什么,为什么要学习Hadoop? Hadoop是一个分布式系统基础架构,由Apache基金会开发。用户可以在不了解分布式底层细节的情况下,开发分布式程序。充分利用集群的威力高速运算和存储。Hadoop实现了一个分布式...

    hadoop-hive的知识点总结

    hadoop-hive的hql知识点详细总结,纯干货,建表,分区,分桶,hive的dml语句,hive的函数,hive的序列化与反序列化

    16_尚硅谷大数据之MapReduce_Hadoop序列化1

    2.1 序列化概述 2.2 常用数据序列化类型 2.3 自定义 bean 对象实现序列化接口(Writable) 2.4 序列化案例实操

    深入浅析Java Object Serialization与 Hadoop 序列化

    序列化是指将结构化对象转化为字节流以便在网络上传输或者写到磁盘永久存储的过程。下面通过本文给大家分享Java Object Serialization与 Hadoop 序列化,需要的朋友可以参考下

    Hadoop平台技术 序列化操作案例.docx

    Hadoop平台技术 序列化操作案例.docx 学习资料 复习资料 教学资源

    Hadoop权威指南 第二版(中文版)

    Hadoop的I/O、MapReduce应用程序开发;MapReduce的工作机制;MapReduce的类型和格式;MapReduce的特性;如何构建Hadoop集群,如何管理Hadoop;Pig简介;Hbase简介;Hive简介;ZooKeeper简介;开源工具Sqoop,最后还...

    【Hadoop篇09】Hadoop序列化1

    (1)紧凑:高效使用存储空间 (2)快速:读写数据的额外开销小 (3)可扩展:随着通信协议的升级而可升级 (4)互操作:支持多语言的交互 (1)必须实现Writ

    hadoop的经典讲义

    hadoop Common – 是hadoop的核心,包括文件系统、远程调用RPC的序列化函数。 HDSF : 提供高吞吐量的可靠分布式文件系统是 GFS的开源实现。 •Hadoop的文件系统。必须通过hadoop fs 命令来读取。支持分布式。 ...

    Hadoop 2.0 生态系统第三章 序列化Parquet2

    Hadoop 2.0 生态系统第三章 序列化Parquet2

Global site tag (gtag.js) - Google Analytics