目录

1、为什么要序列化?

2、什么是序列化?

3、为什么不用Java的序列化?

4、为什么序列化对Hadoop很重要?

5、Hadoop中定义哪些序列化相关的接口呢?

6、Hadoop 自定义Writable 接口

1、为什么要序列化?

一般来说,"活的"对象只存在内存里,关机断电就没有了。而且"活的"对象只能由本地的进程使用,不能被发送到网络上的另外一台计算机。 然而序列化可以存储"活的"对象,可以将"活的"对象发送到远程计算机。

2、什么是序列化?

序列化就是指将对象(实例)转化为字节流(字符数组)。反序列化就是将字节流转化为对象的逆过程。 于是,如果想把"活的"对象存储到文件,存储这串字节即可,如果想把"活的"对象发送到远程主机,发送这串字节即可,需要对象的时候,做一下反序列化,就能将对象"复活"了。

将对象序列化存储到文件,术语又叫"持久化"。将对象序列化发送到远程计算机,术语又叫"数据通信"。

3、为什么不用Java的序列化?

Java的序列化机制的缺点就是计算量开销大,且序列化的结果体积大太,有时能达到对象大小的数倍乃至十倍。它的引用机制也会导致大文件不能分割的问题。这些缺点使得Java的序列化机制对Hadoop来说是不合适的。于是Hadoop设计了自己的序列化机制。

4、为什么序列化对Hadoop很重要?

  因为Hadoop在集群之间进行通讯或者RPC调用的时候,需要序列化,而且要求序列化要快,且体积要小,占用带宽要小。所以必须理解Hadoop的序列化机制。

  序列化和反序列化在分布式数据处理领域经常出现:进程通信和永久存储。然而Hadoop中各个节点的通信是通过远程调用(RPC)实现的,那么 RPC序列化要求具有以下特点:
    紧凑:紧凑的格式能让我们能充分利用网络带宽,而带宽是数据中心最稀缺的资源
    快速:进程通信形成了分布式系统的骨架,所以需要尽量减少序列化和反序列化的性能开销,这是基本的
    可扩展:协议为了满足新的需求变化,所以控制客户端和服务器过程中,需要直接引进相应的协议,这些是新协议,原序列化方式能支持新的协议报文
    互操作:能支持不同语言写的客户端和服务端进行交互

5、Hadoop中定义哪些序列化相关的接口呢?

Hadoop中定义了两个序列化相关的接口:Writable 接口和 Comparable 接口,这两个接口可以合并成一个接口 WritableComparable

下面我们就了解一下这两个序列化接口:

  • Writable接口

 所有实现了Writable接口的类都可以被序列化和反序列化。 Writable 接口中定义了两个方法,分别为write(DataOutput out)和readFields(DataInput in)。write 用于将对象状态写入二进制格式的DataOutput流,readFields 用于从二进制格式的 DataInput 流中读取对象状态。

 package org.apache.hadoop.io;

 import java.io.DataOutput;

 import java.io.DataInput;

 import java.io.IOException;

 import org.apache.hadoop.classification.InterfaceAudience;

 import org.apache.hadoop.classification.InterfaceStability;

 public interface Writable {
/** * 将对象转换为字节流并写入到输出流out中 */ void write(DataOutput out) throws IOException; /** * 从输入流in中读取字节流反序列化为对象 */ void readFields(DataInput in) throws IOException;
}

对于一个特定的 Writable,我们可以对它进行哪些操作呢?

有两种常用操作:赋值和取值,这里我们以 IntWritable 为例来分别说明(IntWritable是对Java的int类型的封装)

1)通过 set() 函数设置 IntWritable 的值

IntWritable value = new IntWritable();

value.set(588)

类似的,也可以使用构造函数来赋值。

IntWritable value = new IntWritable(588);

2)通过get()函数获取 IntWritable 的值。

int result = value.get();// 这里获取的值为588

  • Comparable接口

  所有实现了Comparable的对象都可以和自身相同类型的对象比较大小。该接口定义为:

 package java.lang;

 import java.util.*;

 public interface Comparable<T> {
/**
* 将this对象和对象o进行比较,约定:返回负数为小于,零为大于,整数为大于
*/
public int compareTo(T o);
}

6、Hadoop 自定义Writable 接口

  虽然 Hadoop 自带一系列Writable实现,如IntWritable,LongWritable等,可以满足一些简单的数据类型。但有时,复杂的数据类型需要自己自定义实现。通过自定义Writable,能够完全控制二进制表示和排序顺序。

  现有的 Hadoop Writable 应用已得到很好的优化,但为了对付更复杂的结构,最好创建一个新的 Writable 类型,而不是使用已有的类型。下面我们来学习一下如何自定义 Writable 类型,以自定义一个Writable 类型TextPair为例,如下所示

 import java.io.*;

 import org.apache.hadoop.io.*;

 /**
* @ProjectName Serialize
* @ClassName TextPair
* @Description 自定义Writable类型TextPair
* @Author 刘吉超
* @Date 2016-04-16 23:59:19
*/
public class TextPair implements WritableComparable<TextPair> {
// Text 类型的实例变量
private Text first;
// Text 类型的实例变量
private Text second; public TextPair() {
set(new Text(), new Text());
} public TextPair(String first, String second) {
set(new Text(first), new Text(second));
} 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 Text getSecond() {
return second;
} @Override
// 将对象转换为字节流并写入到输出流out中
public void write(DataOutput out) throws IOException {
first.write(out);
second.write(out);
} @Override
// 从输入流in中读取字节流反序列化为对象
public void readFields(DataInput in) throws IOException {
first.readFields(in);
second.readFields(in);
} @Override
public int hashCode() {
return first.hashCode() * 163 + second.hashCode();
} @Override
public boolean equals(Object o) {
if (o instanceof TextPair) {
TextPair tp = (TextPair) o;
return first.equals(tp.first) && second.equals(tp.second);
}
return false;
} @Override
public String toString() {
return first + "\t" + second;
} // 排序
@Override
public int compareTo(TextPair tp) {
int cmp = first.compareTo(tp.first);
if (cmp != 0) {
return cmp;
}
return second.compareTo(tp.second);
}
}

  TextPair对象有两个Text实例变量(first和second)、相关的构造函数、get方法和set方法。 所有的Writable实现都必须有一个默认的构造函数,以便MapReduce框架能够对它们进行实例化,进而调用readFields()方法来填充它们的字段。Writable实例是易变的、经常重用的,所以应该尽量避免在 write() 或 readFields() 方法中分配对象。

  通过委托给每个 Text 对象本身,TextPair 的 write() 方法依次序列化输出流中的每一个 Text 对象。同样也通过委托给 Text 对象本身,readFields() 反序列化 输入流中的字节。DataOutput 和 DataInput 接口有丰富的整套方法用于序列化和反序列化 Java 基本类型,所以在一般情况下,能够完全控制 Writable 对象的数据传输格式。

  正如为Java写的任意值对象一样,会重写java.lang.Object的hashCode()、equals()和toString()方法。 HashPartitioner使用hashcode()方法来选择reduce分区,所以应该确保写一个好的哈希函数来确定reduce函数的分区在大小上是相当的。

  TextPair是WritableComparable的实现,所以它提供了compareTo()方法的实现,加入我们希望的排序:通过一个一个String逐个排序

如果,您认为阅读这篇博客让您有些收获,不妨点击一下右下角的【推荐】。
如果,您希望更容易地发现我的新博客,不妨点击一下左下角的【关注我】。
如果,您对我的博客所讲述的内容有兴趣,请继续关注我的后续博客,我是【刘超★ljc】。

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

hadoop文件的序列化的更多相关文章

  1. Hadoop(十一)Hadoop IO之序列化与比较功能实现详解

    前言 上一篇给大家介绍了Hadoop是怎么样保证数据的完整性的,并且使用Java程序来验证了会产生.crc的校验文件.这一篇给大家分享的是Hadoop的序列化! 一.序列化和反序列化概述 1.1.序列 ...

  2. 1 weekend110的复习 + hadoop中的序列化机制 + 流量求和mr程序开发

    以上是,weekend110的yarn的job提交流程源码分析的复习总结 下面呢,来讲weekend110的hadoop中的序列化机制 1363157985066      13726230503  ...

  3. 马士兵hadoop第二课:hdfs集群集中管理和hadoop文件操作

    马士兵hadoop第一课:虚拟机搭建和安装hadoop及启动 马士兵hadoop第二课:hdfs集群集中管理和hadoop文件操作 马士兵hadoop第三课:java开发hdfs 马士兵hadoop第 ...

  4. 马士兵hadoop第二课:hdfs集群集中管理和hadoop文件操作(转)

    马士兵hadoop第一课:虚拟机搭建和安装hadoop及启动 马士兵hadoop第二课:hdfs集群集中管理和hadoop文件操作 马士兵hadoop第三课:java开发hdfs 马士兵hadoop第 ...

  5. hadoop 文件参数配置

    准备环境(省略) 上传实验所需的压缩包 配置网络信息 修改主机名 配置域名解析 关闭防火墙与SELinux(在所有节点上执行)代码如下: systemctl disable --now firewal ...

  6. 一脸懵逼学习Hadoop中的序列化机制——流量求和统计MapReduce的程序开发案例——流量求和统计排序

    一:序列化概念 序列化(Serialization)是指把结构化对象转化为字节流.反序列化(Deserialization)是序列化的逆过程.即把字节流转回结构化对象.Java序列化(java.io. ...

  7. hadoop中的序列化

    此文已由作者肖凡授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 最近在学习hadoop,发现hadoop的序列化过程和jdk的序列化有很大的区别,下面就来说说这两者的区别都有 ...

  8. .net学习之集合、foreach原理、Hashtable、Path类、File类、Directory类、文件流FileStream类、压缩流GZipStream、拷贝大文件、序列化和反序列化

    1.集合(1)ArrayList内部存储数据的是一个object数组,创建这个类的对象的时候,这个对象里的数组的长度为0(2)调用Add方法加元素的时候,如果第一次增加元神,就会将数组的长度变为4往里 ...

  9. Hadoop文件的基本操作

    Hadoop提供了大量的API对文件系统中的文件进行操作,主要包括: (1)读取文件 (2)写文件 (3)读取文件属性 (4)列出文件 (5)删除文件 1、读取文件 以下示例中,将hdfs中的一个文件 ...

随机推荐

  1. PHPCMS GET标签使用

    大纲: get 标签概述get 标签语法get 标签创建工具get 调用本系统示例get 调用其他系统示例一.get 标签概述    通俗来讲,get 标签是Phpcms定义的能直接调用数据库里面内容 ...

  2. prepare—Article【准备篇】之SSH_tool#PuTTY

    第一:下载PuTTY: url :     http://www.openssh.com/ 下载界面: 安装后: 详解以上命令 ① ② PuTTYgen is a key generator. It ...

  3. 【算法】改进的冒泡排序 O(n^2) 稳定的 C语言

    改进的冒泡排序 一.算法描述 基于原冒泡排序 每次选取第一个元素作为主元往后进行比较,若遇到比它小的则放到它左边(即进行交换),若遇到比它大的则选取大的作为主元进行后续比较,每趟选取了无序列中最大元素 ...

  4. 关于执行ST_Geometry的st_centroid函数时报ORA-28579错误的问题

    环境 SDE版本:10./10.2/10.2.1/10.2.2 Oracle版本:11g R2 11.2.0.1 Windows版本:Windows Server 2008 R2 问题描述及原因 以全 ...

  5. Jquery的attr属性

    在JS中设置节点的属性与属性值用到setAttribute(),获得节点的属性与属性值用到getAttribute(),而在jquery中,用一个attr()就可以全部搞定了,赞一个先 ^^ jque ...

  6. [BZOJ 1081] [SCOI2005] 超级格雷码 【找规律】

    题目链接:BZOJ - 1081 备注:此题BZOJ上貌似没有 spj ,要把一般顺序的每个格雷码倒着输出...比如 0102 输出为 2010 题目分析 就是按照 Gray 码的生成方法写前几个出来 ...

  7. Git 忽略已经提交的文件

    如果想在本地忽略某个文件的话执行这个命令: git update-index --assume-unchanged <file> 如果想重新同步这个文件的话执行这个命令. git upda ...

  8. Java正则表达式中的捕获组的概念及相关API使用

    要弄清这三个方法,首先要弄清Java正则表达式中的捕获组的概念.捕获组也就是Pattern中以括号对“()”分割出的子Pattern.至于为什么要用捕获组呢,主要是为了能找出在一次匹配中你更关心的部分 ...

  9. SQL*Net message from client

    SQL*Net message from client The server process (foreground process) waits for a message from the cli ...

  10. Android中moveTo、lineTo、quadTo、cubicTo、arcTo详解(实例)

    1.Why 最近在写android画图经常用到这几个什么什么To,一开始还真不知道cubicTo这个方法,更不用说能不能分清楚它们了,所以特此来做个小笔记,记录下moveTo.lineTo.quadT ...