Hadoop 成长史 --- 从 Nutch 子项目到大数据生态王者
2003 年,Google 发表了三篇论文。一个叫 Doug Cutting 的程序员读后灵光一现,于是他写了一个开源项目。谁也想不到,这个项目日后会成为大数据时代的"操作系统"。
一、开篇:一个人的灵感,一群人的生态
想象一下:你有一份 1TB 的文件,里面是过去十年全国电商的交易记录。你想统计"哪个省份的哪类商品销量最高"。
单机?读一遍这个文件就需要大半天------这还是不考虑 CPU 处理时间的情况。
怎么办?答案只有一个:把文件拆开,让多台机器一起算。
2004 年前后,这就是 Doug Cutting 面临的真实问题。他当时正在做一个开源的搜索引擎 Nutch ,需要对海量网页进行索引。单机搞不定,集群又没有好用的软件框架------于是他决定自己写一个。
二、Hadoop 的前世今生
2.1 Google 的"三驾马车"
2000 年代初,Google 已经是有海量数据的互联网巨头。他们是如何处理 PB 级数据的?2003-2006 年间,Google 公开发表了三篇论文(业界称为 "Google 三驾马车"):
| 论文 | 发表时间 | 解决了什么问题 | 影响 |
|---|---|---|---|
| GFS(Google File System) | 2003 年 | 如何在成百上千台廉价服务器上可靠地存储海量数据 | HDFS 的灵感来源 |
| MapReduce | 2004 年 | 如何对海量数据进行分布式并行计算 | Hadoop MapReduce 的灵感来源 |
| BigTable | 2006 年 | 如何在分布式环境下实现结构化数据的存储和查询 | HBase 的灵感来源 |
这三篇论文的出现,改变了整个大数据产业的走向。以至于后来有人感叹:"Google 不是在写论文,而是在定义行业标准。"
2.2 Doug Cutting 与 Nutch
Doug Cutting 是一位对搜索引擎充满热情的程序员。他开发的 Nutch 是一个开源的搜索引擎------就像当时市面上的 Lucene(也是他开发的)一样,他希望给互联网世界提供一个自由、开放的搜索方案。
但问题来了:要搜索互联网,必须能处理海量的网页数据。Nutch 在单机上跑不动。
读到了 Google 的 GFS 和 MapReduce 论文后,Cutting 像发现新大陆一样------这就是他梦寐以求的架构!
他立刻在 Nutch 中实现了 DFS (分布式文件系统)和 MapReduce 机制。这就是 Hadoop 的雏形。
2.3 从 Nutch 剥离,成为独立项目
随着 DFS 和 MapReduce 在 Nutch 中的成熟,Cutting 意识到:这套分布式处理的框架不只是一个搜索引擎的附属品,它可以独立出来,成为一个通用的平台。
于是,DFS + MapReduce 从 Nutch 中被剥离,起了一个新名字:
Hadoop------这是 Cutting 给他儿子的大象玩具起的名字。后来 Hadoop 的 logo 就是一头黄色的大象 🐘
2006 年,Hadoop 被引入 Apache 基金会,随后迅速发展。
2.4 发展历程时间线
| 时间 / 版本 | 里程碑事件 | 意义 |
|---|---|---|
| 2004-2005 | Cutting 在 Nutch 中实现 DFS 和 MapReduce | Hadoop 的基因诞生 |
| 2006 | Hadoop 从 Nutch 剥离,加入 Apache 基金会 | 独立项目的开始 |
| 早期 | Hive、MapReduce、HDFS、Avro、Chukwa 成为 Hadoop 子项目 | 生态体系初步形成 |
| --- | Hadoop 成为 Apache 顶级项目 | 身份确立 |
| Hadoop 1.0.0 | Avro、HBase、Hive、Pig、ZooKeeper 陆续脱离 Hadoop 成为 Apache 顶级项目 | 生态组件成熟独立 |
| Hadoop 2.0.0-alpha | YARN 框架引入 + Impala 加入生态系统 | 架构大升级 |
| Hadoop 2.0.0 | 正式版发布 | 2.x 时代全面到来 |
| Hadoop 3.0.0 | Spark 成为 Apache 顶级项目 | 生态进一步壮大 |
2.5 Hadoop 的版本演进 --- 为什么需要改进?
Hadoop 1.x 时代的局限
Hadoop 1.0 的核心由两部分组成:
- HDFS:分布式存储
- MapReduce :分布式计算 + 资源管理(耦合在一起)
MapReduce 在 1.x 中既负责任务计算,又负责资源管理。这种架构的后果:
| 问题 | 描述 |
|---|---|
| JobTracker 单点故障 | JobTracker 只有一个,挂了整个集群不能提交新任务 |
| 功能耦合 | MapReduce 既要算数据,又要管资源------两头没讨好 |
| 扩展性差 | 集群超过 4000 个节点时,JobTracker 成为瓶颈 |
| 只支持 MapReduce | 其他计算框架(如 Impala、Spark)无法接入 |
Hadoop 2.x 的改进
Hadoop 2.0 在架构层面做了两件大事:
- 引入 YARN 资源管理框架 → 把"资源管理"从 MapReduce 中拆出来,变成通用组件
- HDFS 高可用(HA) → 解决 NameNode 单点故障
这就是 Hadoop 2.0 最核心的两个改进------解耦 (计算和资源管理分离) + 高可用(不因为一个节点挂了就停摆)。
Hadoop 3.x 的变化
- 支持 erasure coding(纠删码)------比副本节省 50% 存储空间
- 支持多个 NameNode(联邦模式)
- 默认最低 Java 版本升级
三、YARN --- 资源管理的"内阁部长"
3.1 YARN 的设计思想
YARN(Yet Another Resource Negotiator,另一种资源协调者)的核心思想是:
把 Hadoop 1.0 中 JobTracker 的功能拆成两个独立的角色。
Hadoop 1.0: Hadoop 2.0 以后:
┌────────────┐ ┌──────────────────┐
│ JobTracker │ → │ ResourceManager │ ← 全局资源调度
│(既管计算 │ │ (只负责分配资源) │
│ 又管资源) │ ├──────────────────┤
└────────────┘ │ ApplicationMaster │ ← 每个应用一个
│ (只负责本任务) │
└──────────────────┘
3.2 YARN 三大核心组件
① ResourceManager(RM)--- 全局大管家
- 职责:对整个集群的资源(CPU、内存)进行统一管理和分配
- 内部有两个重要组件:
- Scheduler(调度器) :负责将资源分配给各个应用程序,不关心任务状态和监控
- ApplicationsManager :负责接收客户端提交的任务、协商第一个 Container、以及重启失败的 ApplicationMaster
② NodeManager(NM)--- 每个节点的"监工"
- 职责:管理单个节点上的资源,每个节点一个
- 具体工作 :
- 定时向 RM 汇报本节点的资源使用情况(CPU、内存、磁盘)
- 负责启动和停止 Container(任务容器)
- 管理本节点上的任务生命周期
③ ApplicationMaster(AM)--- 每个应用的项目经理
- 职责:每个提交的应用程序对应一个 AM
- 具体工作 :
- 与 RM 协商申请资源(Container)
- 把获得的资源进一步分配给内部的各个任务(二次分配)
- 与 NM 协作,启动/停止任务
- 监控任务执行状态,失败时重新申请资源
打个比方:
- RM 是公司的人力资源部------不关心具体项目怎么做,只负责给项目分配人员名额
- NM 是每个部门的小组长------知道部门里谁在干什么、什么资源被占用了
- AM 是项目经理------拿到名额后,决定让谁做什么事、怎么分工
3.3 YARN 完整工作流程(7 步骤)
下面是一个完整的 YARN 任务执行流程:
Step 1:用户提交应用
│
▼
Step 2:RM 分配第一个 Container → 启动 ApplicationMaster
│
▼
Step 3:AM 向 RM 注册(RM 知道"这个项目的项目经理上线了")
│
▼
Step 4:AM 轮询向 RM 申请资源("老板,我还要 5 个人")
│
▼
Step 5:RM 分配资源 → AM 获得 Container
│
▼
Step 6:AM 通知 NM 启动任务 → NM 设置运行环境并启动
│
▼
Step 7:各任务向 AM 汇报状态 → 全部完成后 AM 向 RM 注销
逐步骤详细解释:
| 步骤 | 动作 | 实现细节 |
|---|---|---|
| 1 | 客户端 Client 向 YARN 提交 Application | 包含任务代码、配置、输入输出路径等信息 |
| 2 | RM 的调度器为应用分配一个 Container | 这个 Container 用来运行 ApplicationMaster |
| 3 | AM 被创建后,向 RM 注册 | RM 可以在 Web UI 上显示应用运行状态 |
| 4 | AM 采用轮询方式通过 RPC 向 RM 申请资源 | AM 会估算计算所需的资源量,分批申请 |
| 5 | RM 向 AM 分配 Container | Container 是资源分配的单位(指定 CPU 核数 + 内存大小) |
| 6 | NM 为任务设置好运行环境 | 把任务启动命令写入一个脚本 → 运行该脚本启动任务 |
| 7 | 各任务通过 RPC 向 AM 汇报状态 | 如果任务失败,AM 负责重新申请资源重启任务;全部完成 → AM 向 RM 注销并关闭自己 |
3.4 YARN 的优势
- 通用性:不只是 MapReduce,Spark、Flink 等计算框架都可以跑在 YARN 上
- 可扩展性:ResourceManager 的职责比 JobTracker 轻很多,集群规模可以更大
- 高利用率:资源细粒度分配,多个框架共享集群资源
- 高可用:RM 可以配置主备模式
四、HDFS 高可用架构 --- 解决单点故障
4.1 单点故障问题
在 Hadoop 1.0 中,NameNode 是 HDFS 的"大脑"------元数据全部存储在 NameNode 的内存中。如果 NameNode 挂了,整个 HDFS 集群就无法访问,所有数据"失联"。
就像图书馆的目录系统管理员突然消失------书都还在书架上,但没人知道哪本书在哪个位置。
4.2 高可用(HA)设计
Hadoop 2.0 引入了 HDFS High Availability(高可用) 机制:
┌──────────────┐ ZooKeeper ┌──────────────┐
│ NameNode │ ◄──────────────► │ NameNode │
│ (Active) │ │ (Standby) │
│ 正在服务 │ │ 热备 │
└──────┬───────┘ └──────┬───────┘
│ │
▼ ▼
DataNode 1 ─ DataNode 2 ─ DataNode 3 ─ DataNode 4 ...
(所有 DataNode 同时向 Active 和 Standby 汇报)
核心设计要点:
| 角色 | 职责 |
|---|---|
| Active NameNode | 处理所有客户端请求(读写、增删改等) |
| Standby NameNode | 随时准备接替,保持最新的元数据状态 |
| ZooKeeper | 协调者,监控 NameNode 健康状态 |
| ZKFC(故障恢复控制器) | 每个 NameNode 配一个,负责发送心跳给 ZooKeeper |
4.3 故障转移流程
正常运行:
Active NN 正常工作 → ZKFC 定期发心跳 → ZooKeeper 知道"Active 活着"
故障发生:
Active NN 宕机 → ZKFC 检测到心跳停止 → ZooKeeper 通知 Standby
故障恢复:
Standby NN 的 ZKFC 收到通知 → 将 Standby 切换为 Active → 接管服务
整个过程通常是自动 的,从故障发生到服务恢复一般在 几十秒 以内。
4.4 数据一致性保证
Standby NameNode 要保持和 Active NameNode 数据一致,否则切换后会丢失数据。这是如何保证的?
- JournalNode 共享编辑日志:Active NN 把每次修改操作写入 JournalNode 集群(通常是 3 个节点),Standby NN 从 JournalNode 读取并应用这些操作
- DataNode 同时向两个 NN 汇报块信息:保证 Standby NN 的块映射表也是最新的
通过这种方式,当 Active 宕机时,Standby 可以无缝接替,不会丢失数据,也不会丢失已经提交的写操作。
五、Hadoop 生态系统一览
经过十几年的发展,Hadoop 从最初的 HDFS + MapReduce,成长为一个庞大的生态系统:
┌──────────────────────┐
│ ZooKeeper(协调服务) │
└──────────────────────┘
│
┌───────┐ ┌───────┐ ┌───────┴───────┐ ┌───────┐ ┌───────┐
│ Flume │ │ Sqoop │ │ HBase │ │ Hive │ │ Pig │
│ 日志采集│ │ 数据迁移│ │ 列式数据库 │ │ 数据仓库│ │ 脚本语言│
└───────┘ └───────┘ └───────────────┘ └───────┘ └───────┘
│
┌──────────┴──────────┐
│ MapReduce / Tez │ ← 计算引擎
│ Spark / Impala │
└──────────┬──────────┘
│
┌──────────┴──────────┐
│ YARN │ ← 资源管理
└──────────┬──────────┘
│
┌──────────┴──────────┐
│ HDFS │ ← 分布式存储
└─────────────────────┘
| 组件 | 一句话定位 | 典型场景 |
|---|---|---|
| HDFS | 分布式文件系统,数据存储的基石 | 存储 PB 级文件 |
| MapReduce | 分布式计算框架,分而治之 | 大规模数据批处理 |
| YARN | 资源管理和调度平台 | 统一管理集群资源 |
| Hive | 基于 Hadoop 的数据仓库,SQL 查询 | 分析师用 SQL 查大数据 |
| HBase | 分布式列式数据库,实时读写 | 实时在线查询(如 Facebook 消息) |
| Pig | 数据流脚本语言 | 简化 MapReduce 编程 |
| ZooKeeper | 分布式协调服务 | 配置管理、命名服务、分布式锁 |
| Flume | 日志采集和聚合系统 | 收集 Web 服务器日志到 HDFS |
| Sqoop | 数据导入导出工具 | HDFS ↔ 传统数据库 |
| Mahout | 机器学习算法库 | 推荐系统、聚类、分类 |
| Spark | 内存分布式计算引擎 | 比 MapReduce 快 10-100 倍 |
| Impala | 实时 SQL 查询引擎 | 交互式分析(秒级响应) |
六、篇末小结
Hadoop 的核心定位
Hadoop 是一个能够对大量数据进行分布式处理的软件框架。 用户可以利用 Hadoop 生态体系开发和处理海量数据。由于 Hadoop 有可靠及高效的处理性能 ,它逐渐成为分析大数据的领先平台。
本篇知识点脉络图
Hadoop 起源
├── Google 三驾马车(GFS/MapReduce/BigTable)
├── Doug Cutting + Nutch 搜索引擎
└── 从 Nutch 剥离 → Apache 顶级项目
│
版本演进 ← 1.0(存储+计算耦合)→ 2.0(YARN + HA)→ 3.0(纠删码/联邦)
│
├── YARN 架构
│ ├── ResourceManager(全局调度)
│ ├── NodeManager(节点管理)
│ ├── ApplicationMaster(任务协调)
│ └── 7 步骤工作流程
│
├── HDFS HA
│ ├── Active / Standby 双 NameNode
│ ├── ZKFC + ZooKeeper 自动故障转移
│ └── JournalNode 共享编辑日志
│
└── 生态系统全景(HBase / Hive / Spark......)
下一篇预告:深入 HDFS 内部------什么是 NameNode?DataNode 如何工作?128MB 的数据块是怎么来的?读写数据的 Pipeline 流水线是怎么建立的?还会用 Java 代码操作 HDFS,从理论到实战,一篇搞定。