选择合适的Hadoop数据类型

Hadoop使用基于Writable接口的类作为用于MapReduce计算的数据类型。 为MR计算工作流的输入数据、中间数据和输出数据选择合适的Writable数据类型,对于MapReduce程序的性能和可编程性有巨大的影响。

如果某个数据类型要被用作一个MapReduce计算的value数据类型,那么该数据类型必须实现org.apache.hadoop.io.Writable接口。该Writable接口定义了在传输和存储该数据时Hadoop应该怎样序列化和反序列化这个值。

如果某个数据类型要被用作一个MapReduce计算的key数据类型,那么该数据类型必须实现org.apache.hadoop.io.WritableComparable<T>接口。除了Writable接口的功能外,该WritableComparable接口进一步定义了怎样对这个类型的key实例相互进行比较(用于排序的目的)。

Hadoop提供了许多原始数据类型,如IntWritable、LongWritable、BooleanWritable、FloatWritable和ByteWritable,这些是对应的Java原始数据类型的Writable版本。我们可以用这些类型当作key的类型或value的类型均可。

下面这些Hadoop内置的数据类型也均可被用于key和value的数据类型:

  • Text:存储UTF8文本;
  • BytesWritable:存储一个字节序列;
  • VIntWritable和VLongWritable:这些存储可变长度的整数和long值;
  • NullWritable:这是一个零长度(zero-length)的Writable类型,当不想使用一个key或value类型时使用它;

下面这些Hadoop内置集合数据类型,只能被用作value类型:

1. ArrayWritable:存储Writable类型的值的数组。 要想使用ArrayWritable类型作为Reducer的输入的value类型,我们需要创建一个ArrayWritable的子类来指定它要存储的Writable值的类型:

public class LongArrayWritable extends ArrayWritable {
    public LongArrayWritable() {
        super(LongWritable.class);
    }
}

2. TwoDArrayWritable:用来存储一个属于相同Writable类型的值的矩阵。 要使用该TwoDArrayWritable类型作为Reducer的输入的value类型,我们需要通过创建该TwoDArrayWritable类的一个子类来指定存储的值的类型(类似于ArrayWritable类型):

public class LongTwoDArrayWritable extends TwoDArrayWritable {
    public LongTwoDArrayWritable() {
        super(LongWritable.class);
    }
}

3. MapWritable:这是用来存储一个key-value对的map。keys和values应该都是Writable数据类型。 可以像下面这样使用该MapWritable函数。不过,我们应该意识到,由于包含了存储在该map中的每个对象的类名,所以MapWritable的序列化增加了轻微的性能损失。

MapWritable valueMap = new MapWritable();
valueMap.put(new IntWritable(1),new Text("test"));

4. SortedMapWritable:这个类型存储一个排序的key-value对map。key应该实现WritableComparable接口。SortedMapWritable的用法与MapWritable函数类似。


《Spark原理深入与编程实战》