Hadoop 的 MapReduce 是一种用于处理大规模数据集的分布式计算框架,基于"分而治之"思想设计。以下从核心概念、工作流程、代码结构、优缺点和应用场景等方面详细讲解:
一、MapReduce 核心概念
-
核心思想:
- Map(映射):将输入数据拆分为多个片段,由多个节点并行处理,生成中间键值对(Key-Value)。
- Reduce(归约):将中间结果按 Key 分组,汇总后生成最终结果。
-
设计目标:
- 横向扩展(Scalability):通过增加节点处理 PB 级数据。
- 容错性(Fault Tolerance):自动重试失败的任务。
- 数据本地化(Data Locality):将计算任务调度到数据所在节点,减少网络传输。
二、MapReduce 工作流程
-
输入分片(Input Splits):
- 输入文件被划分为固定大小的分片(如 128MB),每个分片由一个 Map 任务处理。
-
Map 阶段:
- 每个 Map 任务读取分片数据,逐行处理并生成中间键值对(例如
(word, 1)
)。 - 输出结果缓存在内存,定期写入本地磁盘。
- 每个 Map 任务读取分片数据,逐行处理并生成中间键值对(例如
-
Shuffle & Sort 阶段:
- Shuffle:将相同 Key 的中间结果从所有 Map 节点收集到 Reduce 节点。
- Sort:按 Key 对中间结果排序,便于 Reduce 处理。
-
Reduce 阶段:
- 每个 Reduce 任务处理一组 Key,对 Value 列表进行汇总(如求和、去重等)。
- 结果写入 HDFS(Hadoop 分布式文件系统)。
-
输出:
- 最终结果存储在 HDFS 中,格式为
part-r-00000
等文件。
- 最终结果存储在 HDFS 中,格式为
三、代码结构示例(Word Count)
以 Java 实现的经典词频统计为例:
java
// Mapper 类
public class WordCountMapper extends Mapper<LongWritable, Text, Text, IntWritable> {
private final static IntWritable one = new IntWritable(1);
private Text word = new Text();
public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
String line = value.toString();
String[] words = line.split(" ");
for (String w : words) {
word.set(w);
context.write(word, one); // 输出: (word, 1)
}
}
}
// Reducer 类
public class WordCountReducer extends Reducer<Text, IntWritable, Text, IntWritable> {
private IntWritable result = new IntWritable();
public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
int sum = 0;
for (IntWritable val : values) {
sum += val.get(); // 对相同 Key 的 Value 求和
}
result.set(sum);
context.write(key, result); // 输出: (word, total_count)
}
}
// Driver 类(配置任务)
public class WordCount {
public static void main(String[] args) throws Exception {
Job job = Job.getInstance(new Configuration(), "word count");
job.setJarByClass(WordCount.class);
job.setMapperClass(WordCountMapper.class);
job.setReducerClass(WordCountReducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
FileInputFormat.addInputPath(job, new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1]));
System.exit(job.waitForCompletion(true) ? 0 : 1);
}
}
四、MapReduce 的优缺点
-
优点:
- 处理海量数据:横向扩展至数千台节点。
- 容错机制:自动重新执行失败的任务。
- 简单编程模型:只需实现 Map 和 Reduce 函数。
-
缺点:
- 高延迟:适合批处理,不适合实时计算。
- 中间结果写磁盘:Shuffle 阶段产生大量 I/O 开销(对比 Spark 基于内存的计算)。
五、典型应用场景
- 批处理任务 :
- 日志分析、数据清洗、ETL(数据转换)。
- 统计与聚合 :
- 词频统计、网页排名(PageRank)、用户行为分析。
- 复杂计算 :
- 机器学习模型训练(如朴素贝叶斯)、推荐系统。
六、MapReduce vs. 其他框架
特性 | MapReduce | Apache Spark |
---|---|---|
计算模式 | 基于磁盘的批处理 | 基于内存的批处理/流处理 |
延迟 | 高(分钟级) | 低(秒级) |
编程模型 | Map + Reduce | RDD/DataFrame |
适用场景 | 离线大数据分析 | 实时计算、迭代算法 |
七、总结
MapReduce 是 Hadoop 生态的核心计算模型,通过 Map、Shuffle、Reduce 三个阶段实现分布式计算。尽管在实时性上存在不足,但其高可靠性和扩展性使其在大数据离线处理领域仍有一席之地。理解 MapReduce 的原理是掌握 Hadoop 和分布式计算的基础。