wordCount的解析
MapReduce的过程
(input)<k1, v1>->map-><k2, v2>->combine-><k2, v2>->reduce-><k3,v3>(output)
适合用 MapReduce 来处理的数据集(或任务)有一个基本要求: 待处理的数据集可以分解成许多小的数据集,而且每一个小数据集都可以完全并行地进行处理。
计算模型的核心是 Map 和 Reduce 两个函数,这两个函数由用户负责实现,功能是按一定的映射规则将输入的 <key, value> 对转换成另一个或一批 <key, value> 对输出。
下面以WordCount为例说明下MapReduce的过程
函数 | 输入 | wordcount中的输入 | 输出 | wordcount中的输出 |
map | <k1, v1> |
<行在文件中的偏移位置, 文件中的一行>
|
List(<k2,v2>)
|
List<单词,1(代表单词出现了一次)>
|
reduce |
<k2,List(v2)>
|
<单词,List(1(代表单词出现了一次))>
|
<k3,v3>
|
<单词,单词出现次数>
|
<k1,v1> 是 <行在文件中的偏移位置, 文件中的一行>,经 Map 函数映射之后,形成一批中间结果 <单词,出现次数>, 而 Reduce 函数则可以对中间结果进行处理,将相同单词的出现次数进行累加,得到每个单词的总的出现次数。
下面结合wordCount的源码说明
public static class TokenizerMapper extends
Mapper<Object, Text, Text, IntWritable> {
private final static IntWritable one = new IntWritable(1);//IntWritable为hadoop的int io类
private Text word = new Text();//Text为hadoop的文本io类
@Override
public void map(Object key, Text value, Context context)//map接口,参数key value 对应k1,v1
throws IOException, InterruptedException {
Mapper<Object, Text, Text, IntWritable> {
private final static IntWritable one = new IntWritable(1);//IntWritable为hadoop的int io类
private Text word = new Text();//Text为hadoop的文本io类
@Override
public void map(Object key, Text value, Context context)//map接口,参数key value 对应k1,v1
throws IOException, InterruptedException {
//StringTokenizer是一个分割单词的流
StringTokenizer itr = new StringTokenizer(value.toString());
//循环读取Text中的单词
while (itr.hasMoreTokens()) {
this.word.set(itr.nextToken());
context.write(this.word, one);//这里输出<k2,v2> 即<单词,1(代表单词出现了一次)> 在循环中输出,所以输出多个,即输出一个List<k2,v2>
}
}
}
this.word.set(itr.nextToken());
context.write(this.word, one);//这里输出<k2,v2> 即<单词,1(代表单词出现了一次)> 在循环中输出,所以输出多个,即输出一个List<k2,v2>
}
}
}
public static class IntSumReducer extends
Reducer<Text, IntWritable, Text, IntWritable> {
private IntWritable result = new IntWritable();//IntWritable为hadoop的int io类
@Override
public void reduce(Text key, Iterable<IntWritable> values,
Context context) throws IOException, InterruptedException {//reduce接口,参数key value 对应k2 List<v2>
int sum = 0;
Reducer<Text, IntWritable, Text, IntWritable> {
private IntWritable result = new IntWritable();//IntWritable为hadoop的int io类
@Override
public void reduce(Text key, Iterable<IntWritable> values,
Context context) throws IOException, InterruptedException {//reduce接口,参数key value 对应k2 List<v2>
int sum = 0;
//循环遍历List<v2>
for (IntWritable val : values) {
sum += val.get();//get到的都是1,每执行一次+1
}
this.result.set(sum);
context.write(key, this.result);//<k3,v3> k3为单词,v3对应出现次数
}
}
for (IntWritable val : values) {
sum += val.get();//get到的都是1,每执行一次+1
}
this.result.set(sum);
context.write(key, this.result);//<k3,v3> k3为单词,v3对应出现次数
}
}