返回 导航

大数据

hangge.com

Hadoop - 序列化机制详解(附:与Java原生序列化对比样例)

作者:hangge | 2024-07-05 08:32

1,什么是序列化和反序列化?

(1)序列化就是把内存中的对象,转换成字节序列(或其他数据传输协议)以便于存储到磁盘(持久化)和网络传输。 
(2)反序列化就是将收到字节序列(或其他数据传输协议)或者是磁盘的持久化数据,转换成内存中的对象。

2,序列化机制在 Hadoop 中的作用

(1)数据传输:在 Hadoop 的分布式架构中,数据需要在不同节点之间传输。序列化将数据对象转化为字节流,使得这些数据可以通过网络进行传输。
  • 例如,在 MapReduce 框架中,map 任务产生的中间数据需要传输到 reduce 任务所在的节点,这就需要通过序列化来实现。
(2)数据存储Hadoop 的分布式文件系统 HDFSHadoop Distributed File System)存储的数据也是通过序列化的方式进行持久化的。序列化后的数据更为紧凑,节省存储空间,并且能够快速进行读写操作。
  • 例如,SequenceFile 格式就是 Hadoop 中常用的一种二进制文件格式,通过序列化存储键值对数据。

3,为什么不用 Java 的序列化

    Java 的序列化是一个重量级序列化框架(Serializable),一个对象被序列化后,会附带很多额外的信息(各种校验信息,Header,继承体系等),不便于在网络中高效传输。所以,Hadoop 自己开发了一套序列化机制(Writable)。

4,Hadoop 序列化优势

(1)紧凑Hadoop 中最稀缺的资源是宽带,所以紧凑的序列化机制可以充分的利用宽带。 
(2)快速:通信时大量使用序列化机制,因此,需要减少序列化和反序列化的开销。 
(3)可扩展:随着通信协议的升级而可升级。 
(4)互操作:支持不同开发语言的通信。 

5,Hadoop 提供的序列化类

下面是 Hadoop 中提供的常用的基本数据类型的序列化类:
Java 基本类型 Writable 序列化大小(字节)
布尔型(boolean BooleanWritable 1
字节型(byte ByteWritable 1
整型(int IntWritable 4
VIntWritable 1~5
浮点型(float FloatWritable 4
长整型(long LongWritable 8
VLongWritable 1~9
双精度浮点型(double DoubleWritable 8

附:Java 序列化机制与 Hadoop 序列化机制对比样例 

(1)下面是一个 Java 的序列化代码,它将一个 Student 对象序列化后写入到本地文件中:
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

/**
 * Java中的序列化机制
 */
public class JavaSerialize {
  public static void main(String[] args)throws Exception {
    //创建Student对象,并设置id和name属性
    StudentJava studentJava = new StudentJava();
    studentJava.setId(1L);
    studentJava.setName("hangge");

    //将Student对象的当前状态写入本地文件中
    FileOutputStream fos = new FileOutputStream("/Volumes/BOOTCAMP/test/student_java.txt");
    ObjectOutputStream oos = new ObjectOutputStream(fos);
    oos.writeObject(studentJava);
    oos.close();
    fos.close();
  }
}

class StudentJava implements Serializable{

  private static final long serialVersionUID=1L;
  private Long id;
  private String name;

  public Long getId() {
    return id;
  }

  public void setId(Long id) {
    this.id = id;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }
}

(2)下面是使用 Hadoop 序列化机制将 Student 对象序列化后写入到本地文件中:
import org.apache.hadoop.io.Writable;
import java.io.*;

 /**
 * Hadoop中的序列化机制
 */
public class HadoopSerialize {
  public static void main(String[] args) throws Exception{
    //创建Student对象,并设置id和name属性
    StudentWritable studentWritable = new StudentWritable();
    studentWritable.setId(1L);
    studentWritable.setName("hangge");

    //将Student对象的当前状态写入本地文件中
    FileOutputStream fos = new FileOutputStream("/Volumes/BOOTCAMP/test/student_hadoop.txt");
    ObjectOutputStream oos = new ObjectOutputStream(fos);
    studentWritable.write(oos);
    oos.close();
    fos.close();
  }
}

class StudentWritable implements Writable {
  private Long id;
  private String name;

  public Long getId() {
    return id;
  }

  public void setId(Long id) {
    this.id = id;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  @Override
  public void write(DataOutput out) throws IOException {
    out.writeLong(this.id);
    out.writeUTF(this.name);
  }

  @Override
  public void readFields(DataInput in) throws IOException {
    this.id = in.readLong();
    this.name = in.readUTF();
  }
}

(3)对比生成的两个文件的大小,可以发现 Java 序列化的文件大小将近是 Hadoop 序列化文件大小的 10 倍左右。
评论

全部评论(0)

回到顶部