学习笔记,整理自《Hadoop权威指南 第3版》
一、序列化
序列化:序列化是将 内存 中的结构化数据 转化为 能在网络上传输 或 磁盘中进行永久保存的二进制流的过程;反序列化:序列化的逆过程;
应用:进程间通信、网络传输、持久化;
Hadoop中是使用的自己的序列化格式Writable,以及结合用Avro弥补一些Writable的不足;
二:Writable接口 相关:
主要是3个接口:
Writable接口
WritableComparable接口
RawComparator接口
Writable接口中主要是两个方法:write 和 readFields
//Writable接口原形 public interface Writabel{ void write(DataOutput out)throws IOException; void readFields(DataInput in) throws IOException; }
WritableComparable接口:继承自Writable接口 和 Comparable<T>接口;即有序列功能,也有比较排序功能;
public interface WritableComparable<T> extends Writable,Comparable<T>{ }
Hadoop自定义比较排序接口:RawComparator接口,该接口允许实现比较数据流中的记录,而不用把数据流反序列化为对象,从而避免了新建对象的额外开销;
可参考:Hadoop-2.4.1学习之RawComparator及其实现
public interface RawComparator<T> extends Comparator<T>{ public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2); }
工具类WritableComparator:a. 充当RawComparator的实例工厂;b. 提供了对原始compare()方法的一个默认实现;
RawComparator<IntWritable> comparator = WritableComparator.get(IntWritable.class); //获取的comparator 即可比较两个IntWritable对象,也可直接比较两个序列化数据: //比较两上IntWritable对象 IntWritable w1 = new IntWritable(163); IntWritable w2 = new IntWritable(67): comparator.compare(w1, w2); //比较其序列化 byte[] b1 = serialize(w1); byte[] b2 = serialize(w2); comparator.compare(b1, 0, b1.length, b2, 0, b2.length);
三、Writable继承图
以上可以看出,包含了除了char类型外 Java基本类型的封装;其中Text对应Java中的String;
四、自定义一个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 void set(Text first, Text second) { this.first = first; this.second = second; } public Text getFirst() { return this.first; } public Text getSecond() { return this.second; } @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); } @Override public int hashCode() { return first.hashCode() * 163 + second.hashCode(); } @Override public boolean equals(Object o) { if (this == o) return true; if (o instanceof TextPair) { TextPair tp = (TextPair) o; return first.equals(tp.first) && second.equals(tp.second); } return false; } @Override public int compareTo(TextPair tp) { int cmp = first.compareTo(tp.first); if (cmp != 0) { return cmp; } return second.compareTo(tp.second); } @Override public String toString() { return first + "\t" + second; } }