写在前面

本文隶属于专栏《1000个问题搞定大数据技术体系》,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢!

本专栏目录结构和文献引用请见1000个问题搞定大数据技术体系

解答

Hadoop序列化机制

在 Hadoop序列化机制中, org.apache.hadoop.io 包中定义了大量的可序列化对象,它们均实现了 Writable 接口中的两个函数。
这两个函数分别是write()和 readFields()函数。

  1. write:将对象写入字节流
  2. readFields:从字节流中解析出对象在 Java 内嵌的序列化机制中,对象只需实现Java类库中的 Serializable 接口, 即可通过调用 Java 的对象输出流方法 ObjectOutputStream.writeObject() 将对象写入流中。
    如果需要将对象从流中读取出来,可以使用 ObjectOutputStream.readObject() 来实现

在 Hadoop中,通过实现一个 Writable 接口完成序列化和反序列化操作。

Hadoop.通过实现 Writable接口中的方法完成序列化和反序列化操作。

Hadoop的这种序列化机制与Java内嵌的序列化机制相比较具有以下优势

  1. 减少垃圾回收:从流中反序列化数据到当前对象,重复使用当前对象,减少了垃圾回收(GC) 。

  2. 减少网络流量:序列化和反序列化对象类型不变,因此可以只保存必要的数据来减少网络流量。

  3. 提升IO效率:由于序列化和反序列化的数据量减少了,配合 Hadoop压缩机制,可以提升I/O效率。

Hadoop Writable 源码解析(3.2.2)

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;

/**
 * 基于数据输入和数据输出实现简单、高效的序列化协议的可序列化对象。
 * <p>
 * Hadoop MapReduce框架中的任何键或值类型都实现这个接口。
 * <p>
 * 实现通常实现一个静态 read(DataInput) 方法,该方法构造一个新实例,调用 readFields(DataInput) 并返回实例
 */
@InterfaceAudience.Public
@InterfaceStability.Stable
public interface Writable {
    /**
     * 将此对象的字段序列化为out
     *
     * @param out 将此对象序列化为的数据输出
     * @throws IOException
     */
    void write(DataOutput out) throws IOException;

    /**
     * 从中反序列化此对象的字段。
     * 为了提高效率,实现应该尽可能重用现有对象中的存储。 参数: in–
     *
     * @param in 要从中反序列化此对象的DataInput。
     * @throws IOException
     */
    void readFields(DataInput in) throws IOException;
}

Hadoop 官方给出的例子

public class MyWritable implements Writable {
    // 一些数据
    private int counter;
    private long timestamp;

    // 默认的构造器,用来支持序列化/反序列化
    MyWritable() {
    }

    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;
    }
}
上一篇 下一篇