接口
serialization,結構化對象轉化為位元組流
deserialization,位元組流轉化為結構化對象
序列化在分布式資料處理的兩大領域經常出現:程序間通信和永久存儲。
Hadoop使用自己的序列化格式Writable,它格式緊湊,速度快,但很難用Java以外的語言進行擴充和使用。
序列化和反序列化函數:
// 傳回b的序列化位元組序列
private static byte[] serialize(Writable b) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
DataOutputStream dataout = new DataOutputStream(out);
b.write(dataout);
dataout.close();
return out.toByteArray();
}
private static byte[] deserialize(Writable b, byte[] bytes) throws IOException {
ByteArrayInputStream in = new ByteArrayInputStream(bytes);
DataInputStream datain = new DataInputStream(in);
b.readFields(datain);
datain.close();
return bytes;
}
在Hadoop中所有的key/value類型必須實作Writable接口,它有兩個方法,分别用于讀(反序列化)和寫(序列化):
package org.apache.hadoop.io;
import java.io.DataOutput;
import java.io.DataInput;
import java.io.IOException;
public interface Writable {
void write(DataOutput out) throws IOException;
void readFields(DataInput in) throws IOException;
}
在MapReduce過程中需要基于key進行反複的排序,任意key類型,都必須實作Comparable接口。
public interface Comparable<T> {
public int compareTo(T o);
}
WritableComparable繼承了Writable和Comparable:
public interface WritableComparable<T> extends Writable, Comparable<T> { }
是以,一些類型,比如IntWritable實作WritableComparable就可以了。
Hadoop提供的一個優化接口是繼承自Comparator的RawComparator:
package org.apache.hadoop.io;
import java.util.Comparator;
public interface RawComparator<T> extends Comparator<T> {
public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2);
}
該接口允許其實作直接比較資料流的記錄,無須先把資料流反序列化為對象。
有點複雜,再說。
由于需要序列化和反序列化,對java對象需要重寫以下幾個方法:
equals方法
hashCode方法
toString方法
預設的無參構造,為了友善反射進行建立對象
基本資料類型
Writable類對Java基本資料類型提供封裝,short和char除外(兩者可以存儲在IntWritable中)。所有的封裝包含get()和set()兩個方法用于讀取或設定封裝的值。
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 |
Text是針對utf-8序列的Writable類。一般可以認為它等價于java.lang.String的Writable。
NullWritable是一個非常特殊的Writable類型,序列化不包含任何字元,僅僅相當于個占位符。你在使用mapreduce時,key或者value在無需使用時,可以定義為NullWritable。
ObjectWritable和GenericWritable。
在org.apache.hadoop.io包中,有4個集合類:ArrayWritable,TwoDArrayWritable,MapWritable和SortedMapWritable。
對于自定義Comparator類型,需要以下幾個步驟:
1、 推薦Comparator類定義在資料類型内部,靜态内部類。實作WritableComparator類。
2、 重寫預設無參構造方法,方法内必須調用父類有參構造方法
3、 重載父類的compare方法,依據具體功能進行重寫。
4、 向WritableComparator類中注冊自定義的Comparator類。
參照IntWritable的實作。