Hadoop数据类型讲解

来源:互联网 发布:php curl get请求参数 编辑:程序博客网 时间:2024/05/18 00:45

序列化

所谓序列化(serialization),是指将结构化对象转化为字节流,以便在网络上传输或写到磁盘进行永久存储。反序列化(deserialization)是指将字节流转回结构化对象的过程。

序列化在分布式数据处理的两大领域经常出现:进程间通讯和永久存储。

在Hadoop中,系统中多个节点上进程间的通信是通过“远程过程调用”(RPC)实现的。RPC协议将消息序列化成二进制流后发送到远程节点,远程节点接着将二进制流反序列化为原始消息。

Hadoop使用自己的序列化格式Writable,它格式紧凑,速度快,但很难用Java以外的语言进行扩展或使用。因为Writable是Hadoop的核心(大多数MapReduce程序都会为键和值使用它)。

数据类型

数据类型都实现Writable接口,以便用这些类型定义的数据可以被序列化进行网络传输和文件传输。

基本数据类型

BooleanWritable:标准布尔型数值       ByteWritable:单字节数值DoubleWritable:双字节数值           FloatWritable:浮点型IntWritable:整形数                  LongWritable:长整数型

实现接口的问题

1)在Hadoop中所有的Key/Value类型必须实现Writable接口,有两个方法,分别用于读(反序列化)和写(序列化)。

这里写图片描述

2)所有的key,必须实现Comparable接口,在MapReduce过程中需要对key/value对进行反复的排序,默认情况下依据key进行排序,我们要实现compara To()方法。所以,通过key既要实现Writable接口,又要实现Comparable接口。Hadoop中提供了一个公共的接口 WritableComparable 。

这里写图片描述

3)由于需要序列化、反序列化、比较,对Java对象需要重写以下几个方法:
I,equals()
II,hashCode()
III,toString()

4)数据类型,必须有一个默认的无参构造方法,为了方便反射,进行创建对象。

5)在自定义数据类型中,建议使用Java原生数据类型,最好不要使用Hadoop对原生类型封装好的数据类型。

RawComparator

对MapReduce来说,类型的比较是非常重要的,因为中间有个基于键的排序阶段,hadoop提供的一个优化接口是继承自Java Comparator的RawComparator接口:

这里写图片描述

该接口允许其实现直接比较数据流中的记录,无需先把数据流反序列化成对象(比如,一开始数据流就是数组,那么可以直接用来比较),这样便避免了新建对象的额外开销。例如,我们根据IntWritable接口实现的comparator实现了compare()方法,该方法可以从每个字节数组b1和b2中读取给定起始位置(s1和s2)以及长度(l1和l2)的一个整数进而直接比较。

自定义Comparator类

在Hadoop中有一个针对Writable数据类型,进行实现的一个通用实现类WritableComparator类。所有的数据类型,只需要继承通用类,再根据需要的具体功能复写相应的compare()方法。

对于自定义Comparator类,需要以下几步:
1)推荐Comparator类定义在数据类型内部,静态内部类,实现WritableComaprator类。

2)重写默认无参构造方法,方法内必须调用父类有参构造方法。

3)重载父类的compare()方法,依据具体功能进行复写。

4)向WritableComparator类中注册自定义的Comparator类

涉及的接口与类

WritableComparator

WritableComparator是对继承自WritableComparable类的RawComparator类的一个通用实现。它提供两个主要功能,第一,它提供了对原始compare()方法的一个默认实现,该方法能够反序列化将在流中进行比较的对象,并调用对象的compare()方法。第二,它充当是RawComparator实例的工厂(已注册Writable的实现)。

NullWritable

NullWritable是Writable的一个特殊类型,它的序列化长度为0,它并不从数据流中读取数据,也不写入数据。它充当占位符,例如:在mapReduce中,如果你不需要使用键或值,就可以将键或值声明为NullWritable——结果是存储常量空值,如果希望存储一系列数值,与键/值对相对,NullWritable也可以用作在SequenceFile中的键。它是一个不可变的单实例类型:通过调用NullWritable.get()方法可以获取这个实例。

ObjectWritable and GenericWritable

ObjectWritable是对Java基本类型(String,enum,Writable,null或这些类型组成的数组)的一个通用封装。它在Hadoop RPC中用于对方法的参数和返回值类型进行封装和解封装。

当一个字段中包含多个类型时,ObjectWritable是非常实用的,例如:如果SequenceFile中的值包含多个类型,就可以将值类型声明为ObjectWritable,并将每个类型封装在一个ObjectWritable中。作为一个通用的机制,每次序列化都写封装类型的名称,这非常浪费空间。如果封装的类型数量比较少并且能够提前知道,那么可以通过使用静态类型的数组,并使用对序列化后的类型的引用加入位置索引提高性能。这是GenericWritable类采取的方法,并且你可以在继承的子类中指定需要支持的类型。

0 0
原创粉丝点击