第一卷:Hadoop 简介与版本演进
1. Hadoop 简介
📌 Hadoop 是什么?
Hadoop 是一个由 Apache 基金会维护的开源大数据框架,专门解决 海量数据的分布式存储与并行计算。
它的设计目标是:
- ✅ 通过普通商用服务器(低成本硬件)搭建集群
- ✅ 提供容错能力(节点宕机不影响整体运行)
- ✅ 能够横向扩展(增加节点即可提升性能)
- ✅ 高吞吐而非低延迟(适合批处理任务)
🔎 核心理念:
- 存储层 HDFS:将大文件切分成数据块,分布式存储到多个节点上,并提供副本机制保证容错。
- 计算层 MapReduce:采用 Map + Reduce 的编程模型,把大规模任务拆分成小任务在各节点并行执行。
- 调度层 YARN(自 Hadoop 2.x 引入):将资源调度从 MapReduce 中解耦,形成通用资源管理平台。
❓ 为什么校招生必须掌握 Hadoop?
- ✅ Hadoop 是大数据学习的“入门课本”,很多企业仍以 Hadoop 生态为基础。
- ✅ 简历中写 Hadoop 项目(日志分析、ETL、用户画像)会让简历更有分量。
- ✅ 面试中,Hadoop 的 HDFS、MapReduce、YARN、1.x/2.x/3.x 差异是高频考点。
图:Hadoop 总体架构(提示词:Hadoop architecture overview diagram)
2. Hadoop 1.x 架构
📌 组成
- 存储层:HDFS(NameNode + DataNode)
- 计算层:MapReduce(JobTracker + TaskTracker)
- 任务调度:由 JobTracker 负责
✅ 优点
- 简单,适合小规模集群(百台服务器以内)
- MapReduce 框架统一管理资源和任务调度
⚠️ 缺陷
- JobTracker 单点瓶颈:负责所有任务调度和资源管理,集群大时压力过大。
- NameNode 单点故障:一旦宕机,整个 HDFS 不可用。
- 固定 Slot 机制:MapSlot 和 ReduceSlot 固定,资源利用率低。
- 扩展性有限:集群规模大约 4000 节点时就会遇到瓶颈。
❓ 面试题:JobTracker 的作用是什么?为什么会成为瓶颈?
✅ 答案:JobTracker 负责接收作业、划分任务、分配到 TaskTracker 节点,并监控任务状态。随着集群规模增大,JobTracker 需要维护成千上万个任务的调度和心跳,导致性能瓶颈,并且它本身也是单点,一旦宕机所有任务失败。
3. Hadoop 2.x —— 引入 YARN
📌 Hadoop 2.x 的重大改进:
- ✅ 引入 YARN:将资源管理与任务调度从 MapReduce 中分离,形成通用资源管理平台。
- ✅ 支持多计算框架:不仅能跑 MapReduce,还能跑 Spark、Flink、Tez 等。
- ✅ HDFS Federation:允许多个 NameNode 管理不同命名空间,突破单点瓶颈。
- ✅ NameNode 高可用(HA):Active/Standby + ZooKeeper 协调,解决 SPOF。
- ✅ Container 动态分配:资源以容器为单位,按需分配,提高利用率。
🔎 意义
- Hadoop 从“MapReduce 专用框架”进化为“通用大数据操作系统”。
- 企业能在一个集群上同时跑离线分析、实时计算、机器学习。
❓ 面试题:Hadoop 2.x 为什么要引入 YARN?
✅ 答案:Hadoop 1.x 中 JobTracker 既管资源又管调度,容易成为单点瓶颈。YARN 将资源管理交给 ResourceManager,将任务调度交给各 ApplicationMaster,实现解耦,提高了扩展性和资源利用率。
图:Hadoop 2.x 架构示意图(提示词:Hadoop 2.x YARN architecture diagram)
4. Hadoop 3.x —— 更加完善
📌 Hadoop 3.x 的新特性:
- ✅ Erasure Coding(纠删码):替代三副本,降低存储开销约 50%。
- ✅ 多 Standby NameNode:支持多个备用,提高可用性。
- ✅ 支持 GPU 调度:适配深度学习等新型任务。
- ✅ 磁盘均衡器:解决 DataNode 内部磁盘存储不均。
- ✅ YARN Timeline Service v2:增强作业历史记录与监控。
❓ 面试题:Hadoop 3.x 的 Erasure Coding 与三副本机制的区别?
✅ 答案:三副本通过复制冗余,可靠但存储开销大;Erasure Coding 通过编码生成校验块,在丢失部分数据块时用校验块恢复,可靠性接近三副本,但存储效率更高,适合冷数据。
图:Hadoop 1.x vs 2.x vs 3.x 演进对比(提示词:Hadoop version comparison diagram)
5. 小结
📌 Hadoop 的三个阶段
- Hadoop 1.x:MapReduce 一统天下,JobTracker + TaskTracker,单点瓶颈严重。
- Hadoop 2.x:YARN 登场,解耦资源与调度,支持多框架,HDFS Federation 与 HA 提升扩展性。
- Hadoop 3.x:进一步优化存储与资源调度,向云与 AI 场景演进。
❓ 面试题:总结 Hadoop 1.x/2.x/3.x 的主要区别
✅ 答案:
- 1.x:JobTracker/TaskTracker,单点瓶颈,固定 Slot,不支持多框架
- 2.x:YARN + Federation + HA,支持多框架,资源利用率提升
- 3.x:Erasure Coding、多 Standby NN、GPU 调度,更贴合新需求
第二卷:HDFS 深入解析
1. HDFS 架构概览
📌 定义
HDFS(Hadoop Distributed File System)是 Hadoop 的核心组件,专门用于在廉价服务器集群上存储海量数据。
✅ 设计目标:
- 存储 超大文件(GB → PB 级别)。
- 提供 高吞吐量(适合批处理)。
- 保证 容错性(节点宕机不影响整体服务)。
- 支持 横向扩展(增加节点即可提升容量与性能)。
🔎 Master/Slave 架构
- NameNode(主节点):管理文件系统命名空间、元数据(文件 → 块 → DataNode)。
- DataNode(从节点):实际存储数据块,执行读写操作。
- Secondary NameNode(辅助节点):定期合并元数据快照与日志,但不是备份节点。
图:HDFS 架构示意图(提示词:HDFS NameNode DataNode architecture diagram)
2. 数据块与副本机制
📌 数据块(Block)
- Hadoop 1.x 默认块大小:64MB
- Hadoop 2.x/3.x 默认块大小:128MB(可调大至 256MB/512MB)
✅ 为什么要切分成块?
- 提高并行度(不同块可分布在不同节点并行计算)。
- 容错粒度更小(只需恢复丢失的块)。
- 方便管理(大文件可拆分存储)。
📌 副本机制(Replication)
- 默认保存 3 副本
- 副本放置策略:
- 第一份:写入客户端所在节点(或随机节点)。
- 第二份:存放在不同机架的节点。
- 第三份:与第二份同机架、不同节点。
✅ 目的:兼顾本地性(读写效率)与跨机架容灾能力。
❓ 面试题:为什么 HDFS 默认块大小是 128MB,而不是很小?
✅ 答案:块太小会导致块数量过多,NameNode 元数据压力过大;块太大会降低并行度。128MB 在大多数情况下是存储与并行度的平衡点。
3. NameNode 与元数据管理
📌 NameNode 职责
- 管理目录树、文件属性(权限、时间戳)。
- 维护文件与数据块的映射关系。
- 记录每个数据块的副本位置。
✅ 元数据存储方式
- 内存:提升访问速度。
- 持久化:
- FsImage:元数据快照。
- EditLog:操作日志。
🔎 启动流程
- NameNode 启动时加载 FsImage 和 EditLog。
- 通过合并生成最新状态。
📌 Secondary NameNode
- 定期合并 FsImage + EditLog,避免日志过大。
- 误区:不是热备节点,无法在 NameNode 宕机时接管服务。
❓ 面试题:Secondary NameNode 的作用是什么?
✅ 答案:它定期从 NameNode 拉取 FsImage 和 EditLog,合并生成新 FsImage,再返回给 NameNode。作用是减轻 NameNode 压力,而不是备份节点。
4. DataNode 与心跳机制
📌 DataNode 职责
- 存储实际数据块。
- 执行客户端的读写请求。
- 定期向 NameNode 发送心跳与块报告。
✅ 心跳(Heartbeat)
- 默认 3 秒一次,证明 DataNode 存活。
- 如果 10 分钟未收到心跳,NameNode 判定 DataNode 宕机。
✅ BlockReport(块报告)
- 默认一小时一次。
- 报告节点存储的所有数据块。
📌 容错与自愈
- 当某 DataNode 宕机,NameNode 安排其他 DataNode 创建新副本。
❓ 面试题:HDFS 如何判断 DataNode 是否失效?
✅ 答案:通过心跳机制。如果在一定时间(默认 10 分钟)内未收到 DataNode 的心跳,则认为该节点失效,并触发副本重建。
5. 文件读写流程
写入流程
- 客户端请求 NameNode 创建文件。
- NameNode 检查是否存在,若无则返回可用 DataNode 列表。
- 客户端将数据切分成块,按流水线方式写入副本。
- 每个 DataNode 写入后将数据转发到下一个副本节点。
- NameNode 更新元数据,写入完成。
读取流程
- 客户端请求 NameNode 获取文件块位置。
- NameNode 返回 DataNode 列表。
- 客户端选择最近的 DataNode,流式读取数据块。
- 客户端拼接数据块,返回完整文件。
图:HDFS 文件读写流程(提示词:HDFS file read write flow diagram)
❓ 面试题:HDFS 写入时如何保证副本一致?
✅ 答案:采用流水线写入方式,客户端写入第一个 DataNode,随后顺序写入后续 DataNode,只有当所有副本写入成功后,才确认该块写入完成。
6. 小文件问题
📌 问题
- 每个文件对应一份元数据,存放在 NameNode 内存。
- 大量小文件(百万级别)会导致 NameNode 内存溢出。
✅ 解决方法
- Hadoop Archive(HAR):将小文件打包成大文件。
- SequenceFile:以键值对方式存储多个小文件。
- ORC/Parquet:适合批量分析的列式存储格式。
❓ 面试题:为什么 HDFS 不适合小文件?
✅ 答案:因为每个文件都需要 NameNode 保存元数据,文件过多会占用大量内存,拖垮 NameNode。解决办法是合并小文件,例如 HAR、SequenceFile、ORC/Parquet。
7. HDFS 高可用与 Federation
📌 问题:Hadoop 1.x 中 NameNode 单点故障,集群可靠性差。
✅ 高可用(HA)
- Active NameNode + Standby NameNode
- 通过 ZooKeeper 进行协调,自动故障切换
- Standby NameNode 与 Active 保持元数据同步
✅ Federation(联邦机制)
- 允许多个 NameNode 管理不同命名空间
- DataNode 同时向多个 NameNode 注册
- 提升元数据服务的扩展性
❓ 面试题:Secondary NameNode 与 Standby NameNode 有什么区别?
✅ 答案:Secondary 只是定期合并 FsImage 和 EditLog,不能接管服务;Standby NameNode 在 HA 架构中可在 Active 宕机后无缝接管服务。
8. Hadoop 3.x 的 Erasure Coding
📌 传统方法:三副本冗余,可靠但存储开销大。
📌 Erasure Coding(纠删码):对 k 个数据块计算出 m 个校验块,当部分数据块丢失时可用校验块恢复。
✅ 优势:存储开销减少 50%,适合冷数据。
⚠️ 缺点:编码/解码计算开销大,不适合频繁写入。
❓ 面试题:HDFS 三副本与 Erasure Coding 有何区别?
✅ 答案:三副本存储简单、恢复快,但浪费空间;Erasure Coding 更节省存储,但恢复开销大。
9. HDFS 优化与调优
✅ 增大块大小(256MB/512MB),减少调度开销。
✅ 开启压缩(Snappy、LZO)减少存储和传输量。
✅ 合并小文件,使用 ORC/Parquet。
✅ 结合 YARN 调度优化内存和 CPU 分配。
10. HDFS 面试题汇总(附答案)
- HDFS 默认块大小是多少?
✅ 答案:Hadoop 1.x 默认 64MB,2.x/3.x 默认 128MB,可配置更大。 - DataNode 如何向 NameNode 汇报状态?
✅ 答案:通过心跳(3 秒一次)和块报告(默认 1 小时一次)。 - Secondary NameNode 的作用是什么?
✅ 答案:定期合并 FsImage 和 EditLog,减轻 NameNode 压力,但不能替代 NameNode。 - 为什么 HDFS 不适合存储小文件?
✅ 答案:小文件过多会导致 NameNode 元数据内存压力过大,常用 HAR/SequenceFile/ORC 合并解决。 - HDFS 如何实现容错?
✅ 答案:通过副本机制(默认 3 副本)和失效检测 + 副本重建实现容错。 - HDFS 副本放置策略是什么?
✅ 答案:第一份在本地或随机节点,第二份在不同机架,第三份在第二份的机架。 - HDFS 的 Erasure Coding 有什么优缺点?
✅ 答案:优点是存储节省一半空间,缺点是计算复杂,恢复慢,不适合热数据。 - HDFS 写入和读取流程?
✅ 答案:写入时由客户端向 NameNode 请求 DataNode 列表,采用流水线方式写入副本;读取时客户端先请求 NameNode,再直接与 DataNode 通信读取数据块
第三卷:MapReduce 深入解析
1. MapReduce 概述
📌 定义
MapReduce 是 Hadoop 最早的分布式计算框架,采用 “分而治之” 思想,将计算拆分为 Map(映射) 和 Reduce(归约) 两个阶段。
✅ 适用场景:
- 批处理任务(日志分析、数据统计)
- 大规模数据的 ETL 处理
- 离线报表计算
⚠️ 不足:
- 延迟较高(每次计算需多次读写 HDFS)
- 不适合实时计算或迭代计算
2. MapReduce 架构
📌 Hadoop 1.x 架构
- JobTracker:接收作业,切分任务,调度到 TaskTracker。
- TaskTracker:运行在每个节点上,执行 Map 或 Reduce 任务。
📌 Hadoop 2.x 架构(MRv2)
- MapReduce 作业运行在 YARN 上。
- 每个作业启动一个 ApplicationMaster,向 ResourceManager 申请资源。
- Task 运行在 Container 中,由 NodeManager 管理。
图:MapReduce 架构演进图(提示词:MapReduce JobTracker vs YARN architecture diagram)
3. MapReduce 执行流程
📌 任务生命周期:
- 提交作业:客户端将作业提交给 JobTracker(1.x)或 ResourceManager(2.x)。
- 切分数据:输入文件按 Block 切分为 InputSplit。
- Map 阶段:每个 InputSplit 交给一个 Map Task,输出中间键值对。
- Shuffle 阶段:对中间结果按 Key 分区、排序,并传输到 Reduce 节点。
- Reduce 阶段:将相同 Key 的数据合并,执行用户定义逻辑,输出结果。
- 写入 HDFS:最终结果写入 HDFS。
3.1 Map 阶段
📌 组件:
- InputSplit:数据切分逻辑。
- RecordReader:负责解析数据为 <key, value> 对。
- Mapper:用户编写逻辑,输出中间键值对。
✅ 示例:词频统计(WordCount)
- 输入:每行一句话
- Map 输出:<单词, 1>
3.2 Shuffle 阶段
📌 Shuffle 是 MapReduce 的“灵魂”,负责将 Map 输出分发给 Reduce。
✅ 包含步骤:
- Partition:将不同 Key 按规则分配到不同 Reduce。
- Sort:对同一 Reduce 内的数据按 Key 排序。
- Combine(可选):本地预聚合,减少传输量。
- Copy & Merge:数据通过网络传输到 Reduce 端并合并。
❓ 面试题:Shuffle 的作用是什么?
✅ 答案:Shuffle 将 Map 的输出按照 Key 分区和排序,确保相同 Key 的数据交给同一个 Reduce 处理,是连接 Map 与 Reduce 的桥梁。
3.3 Reduce 阶段
📌 流程:
- Reducer 接收相同 Key 的所有 Value
- 用户编写逻辑进行聚合/计算
- 输出写入 HDFS
✅ 示例:WordCount
- Reduce 输入:<word, [1,1,1,1]>
- Reduce 输出:<word, count>
4. MapReduce 容错机制
📌 任务失败处理
- Map/Reduce Task 执行失败 → 自动在其他节点重试。
- TaskTracker 宕机 → JobTracker 重新调度任务到其他节点。
📌 Speculative Execution(推测执行)
- 对执行缓慢的任务,在其他节点启动副本任务,谁先完成用谁的结果。
- 防止“拖后腿”节点影响整体作业。
❓ 面试题:Speculative Execution 有什么作用?
✅ 答案:用于解决某些节点速度慢导致任务整体延迟的问题,通过在其他节点并行执行副本来加速作业完成。
5. MapReduce 编程模型
📌 用户需要编写的部分:
- Mapper:定义 Map 逻辑
- Reducer:定义 Reduce 逻辑
- Driver:作业配置与提交
✅ WordCount 代码框架(简化版)
public class WordCount {
public static class TokenizerMapper 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);
}
}
}
public static class IntSumReducer extends Reducer<Text, IntWritable, Text, IntWritable> {
public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
int sum = 0;
for (IntWritable val : values) {
sum += val.get();
}
context.write(key, new IntWritable(sum));
}
}
}
图:MapReduce WordCount 执行流程(提示词:MapReduce WordCount example diagram)
6. MapReduce 优化
✅ 数据压缩:在 Shuffle 阶段使用压缩(Snappy、LZO)减少网络传输量。
✅ Combiner:在 Map 阶段本地预聚合,减少传输数据。
✅ 合理分区:避免数据倾斜,将热点 Key 分散到多个 Reduce。
✅ 增加并行度:调大 Map/Reduce Task 数量,提高集群资源利用率。
✅ 使用合适的数据格式:如 ORC/Parquet,减少存储与 I/O 开销。
❓ 面试题:MapReduce 中数据倾斜如何解决?
✅ 答案:常见方法包括引入随机前缀打散热点 Key、合理设置分区函数、增加 Reduce 数量、对热点 Key 特殊处理等。
7. MapReduce 常见面试题(附答案)
1. MapReduce 的执行流程是什么?
✅ 答案:输入数据切分 → Map 阶段输出中间结果 → Shuffle(分区、排序、传输) → Reduce 阶段聚合 → 输出结果写入 HDFS。
2. Shuffle 阶段的作用是什么?
✅ 答案:将 Map 输出的数据按照 Key 分区和排序,把相同 Key 的数据发送到同一 Reduce,保证结果正确性。
3. Combiner 的作用是什么?
✅ 答案:Combiner 是 MapReduce 的本地聚合器,在 Map 输出后、Shuffle 前对数据进行局部聚合,减少网络传输量。
4. 什么是数据倾斜?如何解决?
✅ 答案:某些 Key 的数据量远大于其他 Key,导致部分 Reduce 负载过重。解决方法包括:自定义分区函数、随机前缀打散、增加 Reduce 数量、对热点 Key 单独处理。
5. 推测执行机制是什么?
✅ 答案:当某任务执行过慢时,系统会在其他节点启动相同的任务副本,谁先完成使用谁的结果,避免整体任务被拖慢。
6. MapReduce 为什么延迟高?
✅ 答案:MapReduce 每个阶段都需要将数据写入磁盘并存储到 HDFS,无法利用内存加速,导致延迟高,适合离线批处理,不适合实时计算。
7. MapReduce 与 Spark 的区别?
✅ 答案:MapReduce 基于磁盘存储,延迟高;Spark 基于内存计算,速度快,适合迭代计算。MapReduce 适合离线大规模处理,Spark 更适合交互式分析和机器学习。
8. 小结
📌 MapReduce 是 Hadoop 的原始计算框架,核心优势在于 简单、容错性强、适合批处理。
⚠️ 但缺点是 延迟高、编程复杂、不适合实时计算,因此 Spark、Flink 等框架逐渐成为主流。
❓ 在面试中,考察重点往往是 执行流程、Shuffle 阶段、容错机制、优化方法,这些必须掌握。
Comments