写在前面
本文隶属于专栏《1000个问题搞定大数据技术体系》,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢!
本专栏目录结构和文献引用请见1000个问题搞定大数据技术体系
解答
Hadoop序列化机制
在 Hadoop序列化机制中, org.apache.hadoop.io 包中定义了大量的可序列化对象,它们均实现了 Writable 接口中的两个函数。
这两个函数分别是write()和 readFields()函数。
- write:将对象写入字节流
- readFields:从字节流中解析出对象在 Java 内嵌的序列化机制中,对象只需实现Java类库中的 Serializable 接口, 即可通过调用 Java 的对象输出流方法 ObjectOutputStream.writeObject() 将对象写入流中。
如果需要将对象从流中读取出来,可以使用 ObjectOutputStream.readObject() 来实现
在 Hadoop中,通过实现一个 Writable 接口完成序列化和反序列化操作。
Hadoop.通过实现 Writable接口中的方法完成序列化和反序列化操作。
Hadoop的这种序列化机制与Java内嵌的序列化机制相比较具有以下优势
-
减少垃圾回收:从流中反序列化数据到当前对象,重复使用当前对象,减少了垃圾回收(GC) 。
-
减少网络流量:序列化和反序列化对象类型不变,因此可以只保存必要的数据来减少网络流量。
-
提升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;
}
}