Hadoop MapReduce 组件详解
MapReduce 是 Hadoop 的核心分布式计算框架,用于在大规模集群上并行处理海量数据(TB/PB 级)。它将复杂的分布式计算抽象为两个简单阶段:Map(映射) 和 Reduce(归约),极大简化了大数据编程模型。
一、核心设计思想
1. 分而治之(Divide and Conquer)
- 将大任务拆分为多个小任务并行处理
- 自动处理节点故障、数据本地性、负载均衡等分布式难题
2. 数据本地化(Data Locality)
- 计算任务尽量调度到存储数据的节点上
- 大幅减少网络传输开销
3. 容错机制
- 任务失败自动重试
- 推测执行(Speculative Execution):对慢任务启动备份任务
二、MapReduce 架构演进
▶ Hadoop 1.x 架构(已淘汰)
采用 Master/Slave 模式:
| JobTracker | Master | 作业调度、任务分配、状态监控 |
| TaskTracker | Slave | 执行具体 Map/Reduce 任务、汇报心跳 |
❌ 缺点:单点故障、扩展性差(最多支持 4000 节点)
▶ Hadoop 2.x+ 架构(YARN 时代)
资源管理与计算框架解耦:
+———————+
| Client | ← 提交作业
+———-+———-+
|
+———-v———-+
| ResourceManager (RM) | ← 集群资源总管
+———-+———-+
|
+———-v———-+
| NodeManager (NM) | ← 单节点资源代理
+———-+———-+
|
+———-v———-+
| ApplicationMaster (AM) | ← 每个作业专属管理者
+———————+
关键组件说明:
| ResourceManager (RM) | 全局资源调度器,管理所有 NodeManager |
| NodeManager (NM) | 单节点资源监控(CPU/内存)、容器生命周期管理 |
| ApplicationMaster (AM) | 每个 MapReduce 作业独占一个,负责: – 向 RM 申请资源 – 与 NM 通信启动 Task – 监控任务状态 – 处理任务失败重试 |
✅ 优势:支持多计算框架(Spark/Flink 等共用 YARN),扩展性达万级节点
三、MapReduce 作业执行流程(8 步详解)
#mermaid-svg-LwqR469kO3wwyCLZ{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-LwqR469kO3wwyCLZ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-LwqR469kO3wwyCLZ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-LwqR469kO3wwyCLZ .error-icon{fill:#552222;}#mermaid-svg-LwqR469kO3wwyCLZ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-LwqR469kO3wwyCLZ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-LwqR469kO3wwyCLZ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-LwqR469kO3wwyCLZ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-LwqR469kO3wwyCLZ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-LwqR469kO3wwyCLZ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-LwqR469kO3wwyCLZ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-LwqR469kO3wwyCLZ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-LwqR469kO3wwyCLZ .marker.cross{stroke:#333333;}#mermaid-svg-LwqR469kO3wwyCLZ svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-LwqR469kO3wwyCLZ p{margin:0;}#mermaid-svg-LwqR469kO3wwyCLZ .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-LwqR469kO3wwyCLZ .cluster-label text{fill:#333;}#mermaid-svg-LwqR469kO3wwyCLZ .cluster-label span{color:#333;}#mermaid-svg-LwqR469kO3wwyCLZ .cluster-label span p{background-color:transparent;}#mermaid-svg-LwqR469kO3wwyCLZ .label text,#mermaid-svg-LwqR469kO3wwyCLZ span{fill:#333;color:#333;}#mermaid-svg-LwqR469kO3wwyCLZ .node rect,#mermaid-svg-LwqR469kO3wwyCLZ .node circle,#mermaid-svg-LwqR469kO3wwyCLZ .node ellipse,#mermaid-svg-LwqR469kO3wwyCLZ .node polygon,#mermaid-svg-LwqR469kO3wwyCLZ .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-LwqR469kO3wwyCLZ .rough-node .label text,#mermaid-svg-LwqR469kO3wwyCLZ .node .label text,#mermaid-svg-LwqR469kO3wwyCLZ .image-shape .label,#mermaid-svg-LwqR469kO3wwyCLZ .icon-shape .label{text-anchor:middle;}#mermaid-svg-LwqR469kO3wwyCLZ .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-LwqR469kO3wwyCLZ .rough-node .label,#mermaid-svg-LwqR469kO3wwyCLZ .node .label,#mermaid-svg-LwqR469kO3wwyCLZ .image-shape .label,#mermaid-svg-LwqR469kO3wwyCLZ .icon-shape .label{text-align:center;}#mermaid-svg-LwqR469kO3wwyCLZ .node.clickable{cursor:pointer;}#mermaid-svg-LwqR469kO3wwyCLZ .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-LwqR469kO3wwyCLZ .arrowheadPath{fill:#333333;}#mermaid-svg-LwqR469kO3wwyCLZ .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-LwqR469kO3wwyCLZ .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-LwqR469kO3wwyCLZ .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-LwqR469kO3wwyCLZ .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-LwqR469kO3wwyCLZ .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-LwqR469kO3wwyCLZ .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-LwqR469kO3wwyCLZ .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-LwqR469kO3wwyCLZ .cluster text{fill:#333;}#mermaid-svg-LwqR469kO3wwyCLZ .cluster span{color:#333;}#mermaid-svg-LwqR469kO3wwyCLZ div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-LwqR469kO3wwyCLZ .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-LwqR469kO3wwyCLZ rect.text{fill:none;stroke-width:0;}#mermaid-svg-LwqR469kO3wwyCLZ .icon-shape,#mermaid-svg-LwqR469kO3wwyCLZ .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-LwqR469kO3wwyCLZ .icon-shape p,#mermaid-svg-LwqR469kO3wwyCLZ .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-LwqR469kO3wwyCLZ .icon-shape .label rect,#mermaid-svg-LwqR469kO3wwyCLZ .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-LwqR469kO3wwyCLZ .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-LwqR469kO3wwyCLZ .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-LwqR469kO3wwyCLZ :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
Client 提交 Job
AM 向 RM 申请 Container
NM 启动 AM
AM 初始化作业
AM 申请 Map Task 资源
NM 启动 Map Task
Map Task 执行 + Shuffle
AM 申请 Reduce Task 资源
NM 启动 Reduce Task
Reduce Task 执行
作业完成
详细步骤:
客户端提交作业
- 上传 JAR 包、配置文件到 HDFS
- 向 ResourceManager 提交 Application
启动 ApplicationMaster
- RM 分配 Container 启动 AM
- AM 向 RM 注册
AM 初始化作业
- 从 HDFS 读取输入分片(Input Splits)
- 计算 Map/Reduce 任务数量
运行 Map 任务
- AM 为每个分片申请 Container
- NM 启动 Map Task
- Map 阶段:map(LongWritable key, Text value, Context context) {
// 处理一行数据 → 输出 <word, 1>
context.write(new Text(word), new IntWritable(1));
}
Shuffle 阶段(最复杂!)
- Map 端:
- 环形缓冲区(默认 100MB)暂存输出
- 溢写(Spill)到磁盘(启用 Combiner 可聚合)
- 合并多个溢写文件
- Reduce 端:
- 拉取(Fetch)所有 Map 输出
- 合并(Merge)相同 Key 的数据
- 关键优化:压缩中间数据(mapreduce.map.output.compress=true)
运行 Reduce 任务
- AM 申请 Reduce Container
- NM 启动 Reduce Task
- Reduce 阶段:reduce(Text key, Iterable<IntWritable> values, Context context) {
int sum = 0;
for (IntWritable val : values) sum += val.get();
context.write(key, new IntWritable(sum)); // 输出 <word, total_count>
}
写入结果
- Reduce 输出写入 HDFS(副本数=3)
作业清理
- AM 通知 RM 作业完成
- 清理临时文件
四、核心组件深度解析
1. InputFormat(输入格式)
- 作用:定义如何切分输入数据
- 常见实现:
- TextInputFormat:按行读取文本(默认)
- SequenceFileInputFormat:读取二进制 SequenceFile
- CombineTextInputFormat:合并小文件(避免过多 Map Task)
2. Mapper / Reducer
- Mapper:处理输入分片 → 生成中间键值对
- Reducer:聚合相同 Key 的值 → 生成最终结果
- 可选组件:
- Combiner:Map 端预聚合(减少 Shuffle 数据量)
- Partitioner:决定 Map 输出发往哪个 Reduce(默认 HashPartitioner)
3. OutputFormat(输出格式)
- 控制结果写入方式(如 TextOutputFormat, SequenceFileOutputFormat)
五、关键特性与优化点
1. 数据本地性(Data Locality)
- 优先级:本地节点 > 同机架 > 跨机架
- 通过 HDFS 块位置信息实现
2. 推测执行(Speculative Execution)
- 检测慢任务(Straggler),启动备份任务
- 配置参数:<property>
<name>mapreduce.map.speculative</name>
<value>true</value>
</property>
3. 内存管理
- Map/Reduce 内存:通过 mapreduce.map.memory.mb 设置
- JVM 重用:mapreduce.job.jvm.numtasks 减少 JVM 启停开销
4. 压缩优化
| Map 输出 | mapreduce.map.output.compress | Snappy(速度快) |
| Job 输出 | mapreduce.output.fileoutputformat.compress | Gzip(压缩率高) |
六、经典案例:WordCount 执行流程
// 输入: "hello world\\nhello hadoop"
// Map 阶段:
// (0, "hello world") → [("hello",1), ("world",1)]
// (12, "hello hadoop") → [("hello",1), ("hadoop",1)]
// Shuffle 后:
// ("hello", [1,1])
// ("world", [1])
// ("hadoop", [1])
// Reduce 阶段:
// ("hello", 2)
// ("world", 1)
// ("hadoop", 1)
七、MapReduce vs 新一代引擎
| 执行模型 | 批处理(磁盘落盘) | DAG 内存计算 |
| 延迟 | 高(分钟级) | 低(秒级) |
| 适用场景 | ETL、离线分析 | 交互式查询、迭代计算 |
| 容错 | 通过重试 | 血统(Lineage)重建 |
💡 现状:MapReduce 仍是 Hadoop 生态的稳定基石,但新项目多选用 Spark/Tez。
总结
MapReduce 的伟大之处在于:
尽管新一代引擎性能更优,但理解 MapReduce 仍是掌握大数据技术栈的必经之路——它奠定了分布式计算的理论基础和工程实践范式。





