阅读目录(Content)

  • 一、序列化和反序列化概述
    • 1.1、序列化和反序列化的定义
    • 1.2、序列化和反序列化的应用
    • 1.3、RPC序列化格式要求
  • 二、Hadoop中和虚序列化相关的接口和类
    • 1.1、Hadoop对基本数据类型的包装
    • 1.2、Writable接口
    • 1.3、实例解释Java和Hadoop数据类型序列化的差别
    • 1.4、在Hadoop中写一个序列化的类
  • 四、Hadoop中和比较相关的接口和类
    • 4.1、WritableComparable接口
    • 4.2、RawComparator接口
    • 4.3、WritableComparator类
  • 五、Hadoop实现序列化和比较功能
    • 5.1、核心代码

前言

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

 

1.1、序列化和反序列化的定义

  1)序列化:将结构化对象转换为字节流的过程,以便在网络上传输或写入到磁盘进行永久存储的过程。
  2)反序列化:将字节流转回一系列的相反过程结构化对象。

  注意:其实流就是字节数组,我们把数据转变成一系列的字节数组(0101这样的数据)

1.2、序列化和反序列化的应用

  1)进程间的通信

  2)持久化存储

1.3、RPC序列化格式要求

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

  将二进制流反序列化为原始信息。通常情况下,RPC序列化格式如下:

    1)紧凑(compact)

      紧凑格式能充分利用网络带宽。

    2)快速(Fast)

      进程间通信形成了分布式系统的骨架,所以需要尽量减少序列化和反序列化的性能开销,这是基本..最基本的。

    3)可扩展(Extensible)

      为了满足新的需求,协议不断变化。所以控制客户端和服务器的过程中,需要直接引进相应的协议。

    4)支持互操作(Interoperable)

      对于某些系统来说,希望能支持以不同语言写的客户端与服务器交互,所以需要设计需要一种特定的格式来满足这一需求。

 

二、Hadoop中和虚序列化相关的接口和类

  在Java中将一个类写为可以序列化的类是实现Serializable接口

  在Hadoop中将一个类写为可以序列化的类是实现Writable接口,它是一个最顶级的接口。

1.1、Hadoop对基本数据类型的包装

  Hadoop参照JDK里面的数据类型实现了自己的数据类型,Hadoop自己实现的原理会使数据更紧凑一些,效率会高一些。序列化之后的字节数组大小会比

  JDK序列化出来的更小一些。

  所有Java基本类型的可写包装器,除了char(可以是存储在IntWritable中)。所有的都有一个get()和set()方法来检索和存储包装值。  

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

  Java中的String对应着Hadoop中的Text,Text可以存储2G的字符串大小。

1.2、Writable接口

  1)Writable接口概述

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

  2)接口中的方法

    Writable接口定义了两个方法:

      一个将其状态写到DataOutput二进制流,另一个从DataInput二进制流读取状态。

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

  3)API中Writable接口的例子:   

Hadoop(十一)Hadoop IO之序列化与比较功能实现详解
 public class MyWritable implements Writable {
       // Some data     
       private int counter;
       private long timestamp;
       
       public void write(DataOutput out) throws IOException {
         out.writeInt(counter);
         out.writeLong(timestamp);
       }
       
       public void readFields(DataInput in) throws IOException {
         counter = in.readInt();
         timestamp = in.readLong();
       }
       
       public static MyWritable read(DataInput in) throws IOException {
         MyWritable w = new MyWritable();
         w.readFields(in);
         return w;
       }
     }
Hadoop(十一)Hadoop IO之序列化与比较功能实现详解

  思考:在Java中已经有序列化和反序列化相关的类和方法,为什么Hadoop还要去自己设计一套呢?

    因为Hadoop认为Java设计的序列化和反序列化相关的类和方法性能不够好,效率太低了。所以就自己设计一套。

  4)Writable的继承关系

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

1.3、实例解释Java和Hadoop数据类型序列化的差别

  1)核心代码

Hadoop(十一)Hadoop IO之序列化与比较功能实现详解
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Writable;

    //测试使用Hadoop序列化和JDK序列化之间的区别
public class SerializationCompare_0010{
    //Writable是Hadoop中所有数据类型的父类(父接口)。
    public static byte[] serialize(Writable writable) throws IOException{
        //这是一种编程思想,因为我们返回的是一个字节数组,所以进行了一下流的转换。
        ByteArrayOutputStream baos=
            new ByteArrayOutputStream();
        ObjectOutputStream oos=
            new ObjectOutputStream(baos);
        writable.write(oos);
        oos.close();
        return baos.toByteArray();
    }

    //能序列化的一定是类类型,所以这里使用int类型的包装类
    public static byte[] serialize(Integer integer) throws IOException{
        ByteArrayOutputStream baos=
            new ByteArrayOutputStream();
        ObjectOutputStream oos=
            new ObjectOutputStream(baos);
        oos.writeInt(integer);
        oos.close();
        return baos.toByteArray();
    }

    public static Writable deserialize(byte[] bytes) throws IOException{
        ByteArrayInputStream bais=
            new ByteArrayInputStream(bytes);
        DataInputStream dis=
            new DataInputStream(bais);
        IntWritable iw=new IntWritable();
        iw.readFields(dis);
        return iw;
    }

    public static void main(String[] args) throws IOException{
        IntWritable iw=new IntWritable(200);
     //hadoop也可以使用set方法传值
        // iw.set(300);
        byte[] bytes=serialize(iw);
        System.out.println("Hadoop:"+bytes.length);
        //Writable deIw=deserialize(bytes);
        //System.out.println("Hadoop Deserialize:"+deIw);

        Integer integer=new Integer(200);
        bytes=serialize(integer);
        System.out.println("Java:"+bytes.length);
    }
}
Hadoop(十一)Hadoop IO之序列化与比较功能实现详解

相关文章:

  • 2021-12-02
  • 2021-10-31
  • 2021-11-05
  • 2023-03-27
  • 2021-10-11
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2021-04-03
  • 2022-01-12
  • 2022-12-23
  • 2021-05-13
相关资源
相似解决方案