------------本文笔记整理自《Hadoop海量数据处理:技术详解与项目实战》范东来
序列化是指将对象转化为字节流以便在网络上传输或写到磁盘进行永久存储,而反序列化是指将字节流转化为对象的过程。Hadoop主要两方面使用序列化技术:IPC(进程间通信)和数据持久化。
Hadoop提供的序列化格式Writable(org.apache.hadoop.io.Writable),相比Java提供的序列化格式Serializable(java.io.Serializable),格式更加紧凑(序列化后的附加信息大大减少)、性能更好的优点,但是很难用Java以外的语言进行扩展。
如下图为Writable接口的定义。其中,write()方法是将对象写入DataOutput二进制流,readFilelds()方法是从DataInput二进制流中反序列化。
《interface》 Writable |
write(DataOutput out) readFields(DataInput in) |
Java类型 | Writable实现 |
Boolean | BooleanWritable |
Byte | ByteWritable |
Int |
IntWritable VintWritable(变长) |
Float | FloatWritable |
Long |
LongWritable VlongWritable(变长) |
Double | DoubleWritable |
String | Text |
null(引用类型默认值) | NullWritable(占位符,序列化长度0) |
如上图是hadoop封装的Java基本类型,都实现了Writable接口,位于org.apache.hadoop.io包下。
还可以自定义Writable类,实现一个字符串对的数据格式。此时不需要直接实现Writable接口,而是实现WritableComparable接口(此接口继承了Writable和Comparable接口),如下代码所示:
package com.hadoop.writable;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.WritableComparable;
/*
* 字符串对
*/
public class TextPair implements WritableComparable<TextPair> {
//封装的字符串对
private Text first;
private Text second;
public TextPair() {
set(new Text(), new Text());
}
public TextPair(String first, String second) {
set(new Text(first), new Text(second));
}
//实现get/set方法
public void set(Text first, Text second) {
this.first = first;
this.second = second;
}
public Text getFirst() {
return first;
}
public Text getSecond() {
return second;
}
//实现Writale接口
@Override
public void write(DataOutput out) throws IOException {
first.write(out);
second.write(out);
}
@Override
public void readFields(DataInput in) throws IOException {
first.readFields(in);
second.readFields(in);
}
//重写Object类的方法
@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;
}
//实现Comparable接口
@Override
public int compareTo(TextPair o) {
int cmp = first.compareTo(o.first);
if (cmp != 0) {
return cmp;
}
return second.compareTo(o.second);
}
}