天天看點

Hadoop的序列化和資料類型

接口

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的實作。