MapReduce任务执行过程研究之Collect过程

最近一直在找工作,写论文,对MapReduce源代码的学习搁置了很久,想来想去认为不能放弃,有意义的事情一定要做好,要做到底,要尽力。前面的文章到后来写的有些心不在焉,有应付之嫌,如今重新拾起,认真学习,认真写下去。MR 2.0已经发布很久了,新架构新思想很值得学习,学无止境啊。

参考书目:

【1】《Java编程思想(第四版)》

【2】《Hadoop 技术内幕:深入解析MapReduce架构设计与实现原理》

【3】《Hadoop 技术内幕:深入解析Hadoop Common和HDFS架构设计与实现原理》

从Map阶段的Collect过程开始吧,力求有所收获。

看MapTask类的入口函数run,根据配置判断启用old mapper或new mapper。如果是前者:

准备一个MapRunner跑用户的map函数。这个MapRunner实现了MapRunnable泛型接口,四个泛型参数分别代表map的输入键值对和输出键值对的类型(INKEY,INVALUE,OUTKEY,OUTVALUE)。对于MapRunner来说,两个泛型参数来自RecordReader<INKEY,INVALUE>对象;另外两个来自OldOutputCollector对象。后者使用MapOutputBuffer<OUTKEY,OUTVALUE>对象构造。MapOutputBuffer类实现了泛型接口MapOutputCollector,因而具有collect功能。这样一个MapRunner就具备了读取数据(read)和输出数据(collect)的功能。MapRunner通过run函数使用上述两个功能对象。

如果是后者,就有了新的一套RecordReader和OutputCollector,并使用了一个Context对象封装上述功能,传入run函数。不打算详细学习这部分内容。

回到old mapper的实现中,前面提到泛型,由于对java中的泛型技术比较陌生,这里详细学习一下MapRunner.run方法中涉及到泛型技术,顺便还有反射的内容。

首先,看RecordReader,它是一个泛型接口。使用泛型而不是普通接口的好处是,实现接口不仅仅具有了接口的功能,同时接口方法的参数和返回值支持多种类型。对于RecordReader来说,支持多种类型的key和value。如果不使用泛型,则在接口中使用key和value类型的基类,这样就只支持基类及其派生类,不支持该派生体系外的类型。Java支持泛型方法,这使得方法能够独立于类产生变化【1】。如果能使用泛型方法解决问题,就不使用泛型类。MapTask类的runOldMapper方法就是一个泛型方法,其签名如下:

private <INKEY,INVALUE,OUTKEY,OUTVALUE>
  void runOldMapper(final JobConf job,
                    final TaskSplitIndex splitIndex,
                    final TaskUmbilicalProtocol umbilical,
                    TaskReporter reporter
                    )
MapTask本身不是个泛型类。四个泛型参数在构造MapRunnable对象时使用:

MapRunnable<INKEY,INVALUE,OUTKEY,OUTVALUE> runner = ReflectionUtils.newInstance(job.getMapRunnerClass(), job);
MapRunnable也是个泛型接口,其run方法的参数RecordReader和OutputCollector使用了泛型参数:

public void run(RecordReader<K1, V1> input, OutputCollector<K2, V2> output,
                  Reporter reporter)
再看runner的构造,使用ReflectionUtils的静态方法实现,该类是MapReduce提供的一个反射工具类。newInstance方法是个静态泛型方法:
public static <T> T newInstance(Class<T> theClass, Configuration conf) {
    T result;
    try {
      Constructor<T> meth = (Constructor<T>) CONSTRUCTOR_CACHE.get(theClass);
      if (meth == null) {
        meth = theClass.getDeclaredConstructor(EMPTY_ARRAY);
        meth.setAccessible(true);
     
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值