目录
3.1.5.SequenceFileOutputFormat
1.MapReduce概述
Hadoop MapReduce是一个软件框架,用于轻松编写应用程序,这些应用程序以可靠、容错的方式在大型集群(数千个节点)的商用硬件上并行大量数据(数TB数据集)。
MapReduce作业通常将输入数据集分割成独立的块,这些块由映射任务以完全并行的方式进行处理。该框架对映射的输出进行排序,然后将其输入到Reduce任务中。通常,作业的输入和输出都存储在文件系统中。该框架负责安排任务,监控它们并重新执行失败的任务。
通常,计算节点和存储节点是相同的,即MapReduce框架和Hadoop分布式文件系统(参见HDFS架构指南)在同一组节点上运行。此配允许框架在已存在数据的节点上有效地调度任务,从而导致整个集群的聚合带宽非常高。
2.MapReduce的基本工作原理
2.1.Map阶段
2.1.1.Map源码解析
public class WordMapper 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 {
String line = value.toString();
StringTokenizer itr = new StringTokenizer(line);
while (itr.hasMoreTokens()) {
word.set(itr.nextToken().toLowerCase());
context.write(word, one);
}
}
}
当我输入“hello world hello”并调用这段代码时,以下时代码的执行过程:
public class WordMapper extends
Mapper<Object, Text, Text, IntWritable> {
初始化Mapper类
private final static IntWritable one = new IntWritable(1);
private Text word = new Text();
这里将输入的数据“hello world hello”,这个字符以Value参数传递给map方法。也就是说此时的map是这样的(偏移量,“hello world hello”)
public void map(Object key, Text value, Context context)
throws IOException, InterruptedException {
String line = value.toString();
StringTokenizer itr = new StringTokenizer(line);
while (itr.hasMoreTokens()) {
word.set(itr.nextToken().toLowerCase());
context.write(word, one);
}
}
执行map方法
String line = value.toString();
输入Text对象value被转换为Java的String类型,并存储在变量line中。此时line的值就是“hello world hello”
StringTokenizer itr = new StringTokenizer(line);
StringTokenizer类用于将字符串line分解成单词。默认情况下是将根据空格来拆分成单词的。
while (itr.hasMoreTokens()) {
word.set(itr.nextToken().toLowerCase());
context.write(word, one);
}
循环遍历每个单词
word.set(itr.nextToken().toLowerCase()); 将当前单词转换为小写,并存储在word中
context.write(word, one);输出键值对,也就是一个单词对应一个one,one表示单词的计数固定为1。所以得出来就是(hello,1),(world,1),(hello,1)。它不仅用于输出键值对,还在整个MapReduce框架中充当与框架交互的接口,允许Mapper将中间数据传递给Reduce阶段。
2.1.2.map端代码总结
Map阶段是MapReduce作业的第一个步骤,主要负责将原始输入数据分解为一系列键值对(key-value pairs)。这个过程通常涉及到如下步骤:
输入数据的分片:原始数据通常存储在HDFS中,并被分割成若干个分片(splits),每个 分片通常对应一个HDFS块。MapReduce框架会为每个分片启动一个Map任务。
数据解析与映射:每个Map任务读取输入分片中的数据,并将其解析为键值对。例如,如果处理的是一个文本文件,Map任务可以将每一行文本作为一个记录,然后将该记录拆分成键值对,通常是单词作为键,出现次数作为值。
中间键值对的生成:通过自定义的Map函数,输入记录被转换为中间的键值对。这些中间的键值对。这些中间结果在整个集群存储,并为后续的shuffle阶段做准备。
示例:在一个单词计数应用中,map函数会将每个单词映射为一个键,值为1( 即出现次数)。比如,“hello world hello” 会被映射为(