第一卷:Hadoop 简介与版本演进

1. Hadoop 简介

📌 Hadoop 是什么?
Hadoop 是一个由 Apache 基金会维护的开源大数据框架,专门解决 海量数据的分布式存储与并行计算
它的设计目标是:

  • ✅ 通过普通商用服务器(低成本硬件)搭建集群
  • ✅ 提供容错能力(节点宕机不影响整体运行)
  • ✅ 能够横向扩展(增加节点即可提升性能)
  • ✅ 高吞吐而非低延迟(适合批处理任务)

🔎 核心理念

  1. 存储层 HDFS:将大文件切分成数据块,分布式存储到多个节点上,并提供副本机制保证容错。
  2. 计算层 MapReduce:采用 Map + Reduce 的编程模型,把大规模任务拆分成小任务在各节点并行执行。
  3. 调度层 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 框架统一管理资源和任务调度

⚠️ 缺陷

  1. JobTracker 单点瓶颈:负责所有任务调度和资源管理,集群大时压力过大。
  2. NameNode 单点故障:一旦宕机,整个 HDFS 不可用。
  3. 固定 Slot 机制:MapSlot 和 ReduceSlot 固定,资源利用率低。
  4. 扩展性有限:集群规模大约 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 的三个阶段

  1. Hadoop 1.x:MapReduce 一统天下,JobTracker + TaskTracker,单点瓶颈严重。
  2. Hadoop 2.x:YARN 登场,解耦资源与调度,支持多框架,HDFS Federation 与 HA 提升扩展性。
  3. 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 副本
  • 副本放置策略:
    1. 第一份:写入客户端所在节点(或随机节点)。
    2. 第二份:存放在不同机架的节点。
    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. 文件读写流程

写入流程

  1. 客户端请求 NameNode 创建文件。
  2. NameNode 检查是否存在,若无则返回可用 DataNode 列表。
  3. 客户端将数据切分成块,按流水线方式写入副本。
  4. 每个 DataNode 写入后将数据转发到下一个副本节点。
  5. NameNode 更新元数据,写入完成。

读取流程

  1. 客户端请求 NameNode 获取文件块位置。
  2. NameNode 返回 DataNode 列表。
  3. 客户端选择最近的 DataNode,流式读取数据块。
  4. 客户端拼接数据块,返回完整文件。

图:HDFS 文件读写流程(提示词:HDFS file read write flow diagram)

❓ 面试题:HDFS 写入时如何保证副本一致?
✅ 答案:采用流水线写入方式,客户端写入第一个 DataNode,随后顺序写入后续 DataNode,只有当所有副本写入成功后,才确认该块写入完成。


6. 小文件问题

📌 问题

  • 每个文件对应一份元数据,存放在 NameNode 内存。
  • 大量小文件(百万级别)会导致 NameNode 内存溢出。

解决方法

  1. Hadoop Archive(HAR):将小文件打包成大文件。
  2. SequenceFile:以键值对方式存储多个小文件。
  3. 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 面试题汇总(附答案)

  1. HDFS 默认块大小是多少?
    ✅ 答案:Hadoop 1.x 默认 64MB,2.x/3.x 默认 128MB,可配置更大。
  2. DataNode 如何向 NameNode 汇报状态?
    ✅ 答案:通过心跳(3 秒一次)和块报告(默认 1 小时一次)。
  3. Secondary NameNode 的作用是什么?
    ✅ 答案:定期合并 FsImage 和 EditLog,减轻 NameNode 压力,但不能替代 NameNode。
  4. 为什么 HDFS 不适合存储小文件?
    ✅ 答案:小文件过多会导致 NameNode 元数据内存压力过大,常用 HAR/SequenceFile/ORC 合并解决。
  5. HDFS 如何实现容错?
    ✅ 答案:通过副本机制(默认 3 副本)和失效检测 + 副本重建实现容错。
  6. HDFS 副本放置策略是什么?
    ✅ 答案:第一份在本地或随机节点,第二份在不同机架,第三份在第二份的机架。
  7. HDFS 的 Erasure Coding 有什么优缺点?
    ✅ 答案:优点是存储节省一半空间,缺点是计算复杂,恢复慢,不适合热数据。
  8. 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 执行流程

📌 任务生命周期

  1. 提交作业:客户端将作业提交给 JobTracker(1.x)或 ResourceManager(2.x)。
  2. 切分数据:输入文件按 Block 切分为 InputSplit。
  3. Map 阶段:每个 InputSplit 交给一个 Map Task,输出中间键值对。
  4. Shuffle 阶段:对中间结果按 Key 分区、排序,并传输到 Reduce 节点。
  5. Reduce 阶段:将相同 Key 的数据合并,执行用户定义逻辑,输出结果。
  6. 写入 HDFS:最终结果写入 HDFS。

3.1 Map 阶段

📌 组件

  • InputSplit:数据切分逻辑。
  • RecordReader:负责解析数据为 <key, value> 对。
  • Mapper:用户编写逻辑,输出中间键值对。

示例:词频统计(WordCount)

  • 输入:每行一句话
  • Map 输出:<单词, 1>

3.2 Shuffle 阶段

📌 Shuffle 是 MapReduce 的“灵魂”,负责将 Map 输出分发给 Reduce。

✅ 包含步骤:

  1. Partition:将不同 Key 按规则分配到不同 Reduce。
  2. Sort:对同一 Reduce 内的数据按 Key 排序。
  3. Combine(可选):本地预聚合,减少传输量。
  4. 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 阶段、容错机制、优化方法,这些必须掌握。