============================================================================
我们要分析的就是如下的过程:
在自定义的Mapper中我们只需要重写map方法,那么每读取一行记录就会调用一次该方法,如下
public class Mapper<KEYIN, VALUEIN, KEYOUT, VALUEOUT> {
public abstract class Context
implements MapContext<KEYIN,VALUEIN,KEYOUT,VALUEOUT> {
}
protected void setup(Context context
) throws IOException, InterruptedException {
// NOTHING
}
@SuppressWarnings(“unchecked”)
protected void map(KEYIN key, VALUEIN value,
Context context) throws IOException, InterruptedException {
context.write((KEYOUT) key, (VALUEOUT) value);
}
protected void cleanup(Context context
) throws IOException, InterruptedException {
// NOTHING
}
public void run(Context context) throws IOException, InterruptedException {
setup(context);
try {
while (context.nextKeyValue()) {
map(context.getCurrentKey(), context.getCurrentValue(), context);
}
} finally {
cleanup(context);
}
}
}
通过源码我们能够看到里面的方法如下
| 方法 | 说明 |
| — | :-- |
| setup | 任务开始的时候执行一次,可以做一些预处理操作 |
| map | 每读取一行记录执行一次,获取KV对 |
| cleanup | 任务结束前执行一次,可以做一些收尾工作,比如setup的时候声明一个变量sum,map阶段累加,最后在cleanup的时候将sum输出,获取统计的结果 |
| run | 当于map task的驱动,将前面的方法组成了一个模板 |
context的类型是Context实现了MapContext
public abstract class Context
implements MapContext<KEYIN,VALUEIN,KEYOUT,VALUEOUT> {
}
MapContext的实现类是MapContextImpl
而nextKeyValue()方法的调用
说明调用的是RecordReader中的方法,而具体是RecordReader中的哪个实现类呢?继续往下。
我们在启动类中设置了输入输出路径。进入FileInputFormat的子类TextFileInputFormat中查看
说明nextKeyValue()其实执行的是RecordReader中的nextKeyValue方法。