序列化

序列化是指将结构化对象转化为字节流,以便在网络上传输或写入磁盘。反序列化是指将字节流转回结构化对象的过程。
在Hadoop中,系统中多个节点上进程间的通信是通过“远程过程调用”(RPC)实现的。RPC协议是将消息序列化成二进制流后进行传输。通常情况下,RPC序列化格式如下:

紧凑
紧凑的格式能够使我们充分利用网络带宽
快速
   进程间通信形成了分布式系统的骨架,所以需要尽量减少序列化和反序列化的开销
可扩展
  协议为了满足新的需求而不断变化,所以在控制客户端和服务器的过程中,需要直接引用相应的协议。
互操作
对某些系统来说,希望能够支持以不同语言写的客户端与服务器交互,所以需要设计一种特定的格式来满足这一需求。

Hadoop的序列化格式

Hadoop使用自己的序列化格式Writable,它格式紧凑,速度快,但很难用Java以外的语言进行扩展或使用。Avro在一定程度上解决了这一不足。想了解的朋友可以看一下Avro总结(RPC/序列化)
Writable类对Java基本类型提供了封装(short和char除外),所有封装都包含get()和set()两个方法用于读取和设置封装的值。

Java基本类型 Writable实现 序列化大小
boolean BooleanWritable 1
byte ByteWritable 1
int IntWritable
VintWritable
4
1~5
float FloatWritable 4
long LongWritable
VlongWritable
8
1~9
double DoubleWritable 8

除了上述类型之外,还有一种Text类型,它是针对UTF-8序列的Writable类。一般可以认为它等价于java.lang.String的Writable。需要注意的是String的长度是其所含char编码单元的个数,但是Text对象的长度却是其UTF-8编码的字节数。

实现定制的Writable

Hadoop的Writable可以满足大部分需求,但有些情况下我们需要根据自己的需求构造一个新的实现,这里举一个栗子,叫做TextPair,就是一对Text。

主要代码

public class TextPair implements WritableComparable<TextPair> {private Text first;private Text second;public TextPair() {set(new Text(), new Text());}public TextPair(Text first, Text second) {set(first, second);}public void set(Text first, Text second) {this.first = first;this.second = second;}public Text getFirst() {return first;}public void setFirst(Text first) {this.first = first;}public Text getSecond() {return second;}public void setSecond(Text second) {this.second = second;}public int compareTo(TextPair tp) {
//        int cmp = first.compareTo(tp.first);
//        if (cmp != 0) {//            return cmp;
//        }
//        return second.compareTo(tp.second);return new FirstComparator().compare(this, tp);}public void write(DataOutput dataOutput) throws IOException {first.write(dataOutput);second.write(dataOutput);}public void readFields(DataInput dataInput) throws IOException {first.readFields(dataInput);second.readFields(dataInput);}@Overridepublic boolean equals(Object o) {if (o instanceof TextPair) {TextPair tp = (TextPair) o;return first.equals(tp.first) && second.equals(tp.second);}return false;}@Overridepublic int hashCode() {return first.hashCode() * 163 + second.hashCode();}@Overridepublic String toString() {return first + "\t" + second;}public static class FirstComparator extends WritableComparator {public static final Text.Comparator TEXT_COMPARATOR = new Text.Comparator();public FirstComparator() {super(TextPair.class);}@Overridepublic int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {try {int firstL1 = WritableUtils.decodeVIntSize(b1[s1]) + readVInt(b1, s1);int firstL2 = WritableUtils.decodeVIntSize(b2[s2]) + readVInt(b2, s2);return TEXT_COMPARATOR.compare(b1, s1, firstL1, b2, s2, firstL2);} catch (IOException e) {throw new IllegalArgumentException(e);}}@Overridepublic int compare(WritableComparable a, WritableComparable b) {if(a instanceof TextPair && b instanceof TextPair) {return ((TextPair) a).first.compareTo(((TextPair) b).first);}return super.compare(a, b);}}
}

测试结果


说明

上面两个运行结果,第一个是使用默认比较器的结果,第二个是定制比较器FirstComparator(只比较第一个Text)。需要注意的是:由于Writable实例具有易变性并且通常可以重用,所以要尽量避免在write()和readFields()函数中分配对象。

java程序员的大数据之路(6):定制的Writable类型相关推荐

  1. java程序员的大数据之路(13):Pig入门

    Pig简介 Pig为大型数据集的处理提供了更高层次的抽象. Pig包括两部分: 用于描述数据流的语言,称为Pig Latin. 用于运行Pig Latin程序的执行环境.当前有两个环境:单JVM中的本 ...

  2. java程序员的大数据之路(3):用maven构建Hadoop项目

    背景 由于Hadoop项目多数是比较大的项目,因此我们选择使用构建工具来构建Hadoop项目,这里我们使用的是maven.当然也可以使用Gradle等比较流行的构建工具 构建过程 这里总结一下我使用I ...

  3. java程序员的大数据之路(7):基于文件的数据结构

    SequenceFile 介绍 由于日志文件中每一条日志记录是一行文本.如果想记录二进制类型,纯文本是不合适的.这种情况下,Hadoop的SequenceFile类非常合适.SequenceFile可 ...

  4. java程序员的大数据之路(1):Hadoop安装

    Hadoop伪分布式安装 从今天开始我会在这里记录在大数据学习方面的方法和遇到的一些问题. 首先从最著名的开源平台Hadoop开始学习.参考安装教程,这个教程比较全面,按照步骤一步步安装即可. 安装时 ...

  5. java程序员的大数据之路(12):Hadoop的守护进程

    关键属性 Hadoop守护进程的关键属性大多标记为final,使作业的配置无法覆盖. 典型的core-site.xml配置文件 <?xml version="1.0"> ...

  6. java程序员的大数据之路(9):MapReduce的类型

    概述 Hadoop的MapReduce中,map和reduce函数遵循如下常规格式: map:(K1,V1) -> list(K2,V2) reduce:(K2,list(V2)) -> ...

  7. java程序员的大数据之路(2):创建第一个Hadoop程序

    环境 Ubuntu 16.04 + Hadoop 2.7.4 + Intellij idea 2017.2 + jdk 1.8 创建过程 新建工程 新建一个工程 输入工程名 可以随便给工程起一个名字, ...

  8. java程序员的大数据之路(15):Pig Latin用户自定义函数

    过滤函数 所有的过滤函数都要继承FilterFunc类,并且实现抽象方法exec(),该方法的返回类型为Boolean. 示例代码如下: package com.udf.filter;import o ...

  9. java程序员的大数据之路(14):Pig Latin

    结构 一个Pig Latin程序由一组语句构成,一个语句可以理解为一个操作,或一个命令.语句必须以分号结束. Pig Latin有两种注释方法,双减号表示单行注释.多行注释可以使用/* 和 */表示. ...

最新文章

  1. c#devexpress GridContorl添加进度条
  2. Immutable-不变模式与不变类-一版
  3. Spring-学习笔记06【Spring的新注解】
  4. MySQL复制--slave设置读取binlog的位置
  5. 查找字符串中要查找的字符串最后一次出现的位置
  6. nginx----linux安装
  7. 第八章节 文件操作一 (文件常用操作)
  8. Foundation框架: 6.NSString的创建和导出
  9. Windows 10 下使用 telnet 客户端/服务端工具进行连接
  10. 智慧城市大数据创新联盟落户高新区
  11. 二维傅里叶变换深度研究-图像与其频域关系
  12. web开发之cdn回源各项目都可以处理
  13. 【经验之谈】谷歌SEO一般具体要做哪些工作?
  14. 《麦肯锡精英的谈判策略》 -豆瓣评分8.2
  15. 学习SEO第一天[笔记不易]
  16. vcs import src < ros2.repos 或 vcs import --input ros2.repos src 下载失败或速度慢
  17. python内置函数返回元素个数_Python内置函数
  18. Mac系统下连接阿里云并运行java程序
  19. IT外包公司的运作模式如何,他们的赚钱之道何在
  20. android1f21ec,polaris.tmall.com

热门文章

  1. 影响女人一生的十部电影
  2. 如果下载百度云禁止下载的东西
  3. 《印象笔记留给你的空间》第5章 建立个人任务管理系统 / 第6章 记录你的人生轨迹
  4. 崔岩的笔记——使用QT在手机端读取传感器蓝牙数据——以BWT901CL传感器为例
  5. 海康、大华、tplink监控摄像头和硬盘录像机接入GB28181平台配置细节
  6. 全国计算机等级考试报名图片信息,2017年全国计算机等级考试报名如何上传图片?...
  7. 03 汽车以太网如何影响ECU和传感器设计
  8. Windows(Wox) 办公提效工具
  9. Vuex 模块化 配合 本地存储
  10. Last.fm - 推动社会音乐革命