【Hadoop权威指南】MapReduce的类型与格式

来源:互联网 发布:java静态常量存储 编辑:程序博客网 时间:2024/05/25 16:39
MapReduce的类型与格式
MapReduce 的类型
map: (k1, v2) à list(k2, v2)
reduce: (k2, list(v2)) à list(k3, v3)

public interface Mapper<K1, V1, K2, V2> extends JobConfigurable, Closeable {
    void map(K1 key, V1 value, OutputCollector<K2, V2> output, Reporter reporter) throws IOException;
}

public interface Reducer<K2, V2, K3, V3> extends JobConfigurable, Closeable {
    void reduce(K2 key, Iterator<V2> values, OutputCollector<K3, V3> output, Reporter reporter) throws IOException;
}
OutputCollector纯粹是为了输出键 /值对,Reporter 用来更新计数和状态信息。
combine函数与 reduce形式相同 ,它是reducer的一个实现,不同之处是它的输出类型是中间的键 /值对类型(K2, V2
combine: (k2, list(v2)) à list(k2, v2)
partition函数将中间的键 /值对(K2, V2 

默认的输入格式是TextInputFormat, 它产生的键类型是 LongWritable(文件中每行中开始的偏移量),值类型是 Text(文本行)。
真正的map 任务数量取决于输入文件的大小以及文件块的大小,而不是 setNumMapTask函数。
默认的mapper IdentityMapper,它将输入的键值原封不动地写入输出中。
public class IdentityMapper<K, V>
    extends MapReduceBase implements Mapper<K, V, K, V> {
    public void map(K key, V val, OutputCollector<K, V> output, Reporter reporter) throws IOException {
        output.collect(key, val);
    }
}
map任务是由 MapRunner负责运行的,后者是MapRunnable的默认实现。
默认的partitioner HashPartitioner,它对每条记录的键进行哈希以觉得该记录属于哪个分区,每个分区对应一个 reducer任务。
默认的reducer IdentityReducer,它也是一个泛型,简单地将所有的输入写到输出中。
记录在发送给reducer之前,会被 MapReduce系统进行咆哮。
默认的输出格式为TextOutputFormat,它将键值转换为字符串,并用 Tab进行分隔,然后一条记录一行地输出。
输入格式
一个输入分片split由单个 map处理,输出分片在org.apache.hadoop.mapred包中的 InputSplit接口。
public interface InputSplit extends Writable {
    long getLength() throws IOException;
    String[] getLocations() throws IOException:
}
InputSplit InputFormat创建,InputFormat 复杂产生输入分片,并将它们分割成记录。
public interface InputFormat<K, V> {
    InputSplit[] getSplits(JobConf job, int numSplits) throws IOException;
    RecordReaderMK, V> getRecordReader(InputSplit split, JobConf job, Reporter reporter) throws IOException;
}
JobClient调用 getSplits方法,将期望的map任务数 numsplits作为操作传入,这是一个参考值。计算好分片数,客户端将它们发送到 jobtrackerjobtracker 便使用其存储位置信息来调度 map任务从而在tasktracker上处理这些分片数据。在 tasktracker上,map 任务将输入分片传给 InputFormatgetRecordReader 方法来获得这个分片的 RecordReaderRecordReader 是该记录上的迭代器, map任务用一个RecordReader生成记录的键值对,然后传给 map参数。
K key = reader.createKey();
V value = reader.createValue();
while(reader.next(key, value)
        mapper.map(key, value, output, reporter);
输出格式