public class Mapper<KEYIN, VALUEIN, KEYOUT, VALUEOUT>
extends Object
将输入键/值对映射到一组中间键/值对。
映射是将输入记录转换为中间记录的单个任务。转换后的中间记录不必与输入记录具有相同的类型。给定的输入对可以映射为零或许多输出对。
Hadoop Map-Reduce框架为由作业的InputFormat生成的每个InputSplit生成一个映射任务。映射器实现可以通过JobContext.getConfiguration()访问作业的Configuration。
框架首先为InputSplit中的每个键/值对调用setup(Mapper.Context),然后是map(Object,Object,Mapper.Context)。最后调用cleanup(Mapper.Context)。
随后,与给定输出键关联的所有中间值都由框架进行分组,并传递给Reducer以确定最终输出。用户可以通过指定两个关键的RawComparator类来控制排序和分组。
映射器的输出按Reducer进行分区。用户可以通过实现自定义分区程序来控制将哪些键(从而记录)转到哪个Reducer。
用户可以选择通过Job.setCombinerClass(Class)指定一个组合器,以执行中间输出的本地聚合,这有助于减少从Mapper传递给Reducer的数据量。
应用程序可以通过配置指定是否以及如何压缩中间输出,以及使用哪些CompressionCodecs。
如果作业的零归约,则Mapper的输出将直接写入OutputFormat,而无需按键进行排序。
例子
public class TokenCounterMapper
extends Mapper<Object, Text, Text, IntWritable>{
private final static IntWritable one = new IntWritable(1);
private Text word = new Text();
public void map(Object key, Text value, Context context) throws IOException, InterruptedException {
StringTokenizer itr = new StringTokenizer(value.toString());
while (itr.hasMoreTokens()) {
word.set(itr.nextToken());
context.write(word, one);
}
}
}
方法
setup做一些初始化的工作
/**
* Called once at the beginning of the task.
*/
protected void setup(Context context
) throws IOException, InterruptedException {
// NOTHING
}
map方法时需要自己重写的方法,主要内容是想要把k1,v1转化成什么样的k2,v2 这个逻辑是关键,是需要程序员自己定义的.
/**
* Called once for each key/value pair in the input split. Most applications
* should override this, but the default is the identity function.
*/
@SuppressWarnings("unchecked")
protected void map(KEYIN key, VALUEIN value,
Context context) throws IOException, InterruptedException {
context.write((KEYOUT) key, (VALUEOUT) value);
}
``
cleanup做一些收尾的工作
```java
/**
* Called once at the end of the task.
*/
protected void cleanup(Context context
) throws IOException, InterruptedException {
// NOTHING
}
run方法,对每一个键值对调用map方法…run方法是谁调用的呢?用idea find usage可以查出run方法在什么地方被调用过,如图
/**
* Expert users can override this method for more complete control over the
* execution of the Mapper.
* @param context
* @throws IOException
*/
public void run(Context context) throws IOException, InterruptedException {
setup(context);
try {
while (context.nextKeyValue()) {
map(context.getCurrentKey(), context.getCurrentValue(), context);
}
} finally {
cleanup(context);
}
}