Apache Hadoop 完整知识总结与使用教程
版本参考 :Apache Hadoop 3.4.x(当前最新稳定版)
官方网站 :https://hadoop.apache.org/
文档整理时间:2026 年 4 月
目录
- [Hadoop 概述](#Hadoop 概述)
- 核心架构与组件
- 2.1 HDFS(分布式文件系统)
- 2.2 MapReduce(并行计算框架)
- 2.3 YARN(资源管理器)
- 2.4 Hadoop Common
- [HDFS 详解](#HDFS 详解)
- [MapReduce 详解](#MapReduce 详解)
- [YARN 详解](#YARN 详解)
- [Hadoop 生态系统](#Hadoop 生态系统)
- 安装与环境配置
- 7.1 单节点(伪分布式)安装
- 7.2 多节点集群搭建
- [HDFS 常用命令](#HDFS 常用命令)
- [MapReduce 编程实战(WordCount)](#MapReduce 编程实战(WordCount))
- 核心配置文件详解
- 集群监控与管理
- 高可用(HA)方案
- 性能调优
- [Hadoop 3.x 新特性](#Hadoop 3.x 新特性)
- 常见问题与排查
- 与现代大数据技术的对比
1. Hadoop 概述
1.1 什么是 Hadoop?
Apache Hadoop 是一个开源的分布式存储与计算框架,专为在廉价商用硬件集群上处理海量数据而设计。它使用 Java 语言编写,由 Apache 软件基金会维护,是大数据领域最重要的基础设施之一。
Hadoop 起源于 Google 在 2003~2004 年发表的两篇论文:
- GFS(Google File System) → 孕育了 HDFS
- MapReduce → 孕育了 Hadoop MapReduce
最初由 Doug Cutting 和 Mike Cafarella 开发,最早是 Apache Nutch 搜索引擎项目的基础设施,后来捐献给 Apache 基金会独立发展。Yahoo! 在早期对其大规模投入,推动了工业级应用。
1.2 Hadoop 解决了什么问题?
| 传统方案的痛点 | Hadoop 的解法 |
|---|---|
| 单台服务器存储有限 | 横向扩展到成千上万节点 |
| 高性能服务器价格昂贵 | 使用廉价商用机器(commodity hardware) |
| 节点故障导致数据丢失 | 数据多副本冗余存储 |
| 串行处理速度慢 | 数据就近并行计算(Data Locality) |
| 传统数据库无法处理非结构化数据 | 支持结构化、半结构化、非结构化数据 |
1.3 Hadoop 的核心特性
- 可扩展性(Scalability):支持从单台服务器扩展到数千台机器,已验证超过 2000 节点的集群规模。
- 容错性(Fault Tolerance):HDFS 默认将数据块复制 3 份存储在不同节点,任意节点故障不影响数据访问。
- 高吞吐量(High Throughput):HDFS 针对大文件批量读写进行优化,提供极高的聚合带宽。
- 低成本(Cost-Effective):基于廉价硬件,相对于专用高性能服务器大幅降低基础设施成本。
- 灵活性(Flexibility):支持多种数据格式,可存储任意格式的原始数据,在处理时再定义结构。
- 数据本地性(Data Locality):将计算任务移动到数据所在节点,减少网络传输,提升效率。
1.4 Hadoop 发展历程
| 版本 | 时间 | 关键变化 |
|---|---|---|
| Hadoop 0.x | 2006 | 初始版本,包含 HDFS 和 MapReduce |
| Hadoop 1.x | 2011 | 稳定化,但 JobTracker 单点瓶颈明显 |
| Hadoop 2.x | 2013 | 引入 YARN,解耦资源管理与计算 |
| Hadoop 3.x | 2017+ | 纠删码、多 NameNode、GPU 支持、更低存储开销 |
| Hadoop 3.4.x | 2024 | 当前最新稳定版本,包含大量 bug 修复和性能优化 |
2. 核心架构与组件
Hadoop 的架构由四个核心模块组成:
┌──────────────────────────────────────────────────┐
│ Hadoop 生态工具层 │
│ Hive | Pig | HBase | Spark | Sqoop │
├──────────────────────────────────────────────────┤
│ MapReduce / Spark / Tez │ ← 计算层
├──────────────────────────────────────────────────┤
│ YARN(Yet Another Resource Negotiator) │ ← 资源管理层
├──────────────────────────────────────────────────┤
│ HDFS(Hadoop Distributed File System) │ ← 存储层
├──────────────────────────────────────────────────┤
│ Hadoop Common(公共工具库) │ ← 基础层
└──────────────────────────────────────────────────┘
2.1 HDFS(Hadoop Distributed File System)
分布式文件系统,负责数据的分布式存储,是整个 Hadoop 的存储基础。
2.2 MapReduce
并行批处理计算框架,基于 YARN,将大规模数据处理任务分解为 Map 和 Reduce 两个阶段在集群节点上并行执行。
2.3 YARN(Yet Another Resource Negotiator)
集群资源管理与作业调度系统,在 Hadoop 2.0 引入。负责分配 CPU、内存等集群资源给各个计算框架(MapReduce、Spark、Flink 等)。
2.4 Hadoop Common
提供支撑其他模块运行所需的公共工具库、接口和抽象类,包括文件系统抽象、RPC 通信框架、序列化机制等。
3. HDFS 详解
3.1 HDFS 设计目标
HDFS 是专为以下场景优化的分布式文件系统:
- 超大文件:GB、TB 甚至 PB 级别的文件
- 流式数据访问:一次写入,多次读取(Write Once, Read Many)
- 廉价硬件:硬件故障是常态,系统自动容错
- 高吞吐量:优先保证批量读取速度,而非低延迟
HDFS 不适合以下场景:
- 低延迟(毫秒级)数据访问
- 海量小文件存储
- 多用户并发写入同一文件
- 随机写入和修改
3.2 HDFS 架构:主从模式(Master/Slave)
┌─────────────────────────────────┐
│ Client 客户端 │
└─────────────┬───────────────────┘
│ ① 读写请求
▼
┌─────────────────────────────────┐
│ NameNode(主节点) │
│ • 管理文件系统命名空间(元数据) │
│ • 记录文件 → Block 的映射关系 │
│ • 完全运行在内存中 │
│ • 持久化:fsimage + editlog │
└──────────┬──────────────────────┘
│ ② 返回数据块位置
│
┌──────────┴──────────────────────┐
│ │
┌─────▼──────┐ ┌──────────┐ ┌──────▼─────┐
│ DataNode 1 │ │DataNode 2│ │ DataNode 3 │
│ Block A │ │ Block B │ │ Block A' │
│ Block C │ │ Block A' │ │ Block B' │
└────────────┘ └──────────┘ └────────────┘
(数据节点,存储实际数据块,并定期向 NameNode 发送心跳)
NameNode
- 文件系统的主节点(Master),管理整个文件系统的命名空间和元数据
- 不存储实际数据,只存储文件名、目录树、文件到数据块的映射、数据块到 DataNode 的映射
- 完全运行在内存中,持久化依赖两个文件:
- fsimage:文件系统状态的完整快照
- editlog:记录对文件系统的所有修改操作
- 是非 HA 模式下的单点故障(SPOF)
SecondaryNameNode(辅助 NameNode)
- 不是 NameNode 的热备份,常被误解
- 定期合并 editlog 到 fsimage,防止 editlog 过大
- 在生产环境已逐渐被 Standby NameNode(HA 方案)取代
DataNode
- 文件系统的从节点(Slave),负责实际数据的存储和读写
- 每隔固定时间向 NameNode 发送心跳(Heartbeat),报告状态
- 定期向 NameNode 发送块报告(Block Report),汇报本地所有数据块信息
- 执行客户端的读写请求及 NameNode 下达的块复制、删除指令
3.3 数据块(Block)机制
HDFS 将大文件分割为固定大小的数据块(Block):
| Hadoop 版本 | 默认块大小 |
|---|---|
| Hadoop 1.x | 64 MB |
| Hadoop 2.x / 3.x | 128 MB |
为什么块要这么大?
减少寻址开销占比,让传输时间远大于寻道时间,保证高吞吐量。
3.4 数据副本(Replication)策略
默认副本因子为 3,副本放置遵循以下规则(机架感知策略):
-
第 1 个副本:放在写入客户端所在节点(若客户端在集群外,则随机选一个节点)
-
第 2 个副本 :放在与第 1 副本不同机架的某节点
-
第 3 个副本 :放在与第 2 副本相同机架的另一节点
机架 1 机架 2
┌─────────────────┐ ┌─────────────────┐
│ Node A [副本 1] │ │ Node C [副本 2] │
│ Node B │ │ Node D [副本 3] │
└─────────────────┘ └─────────────────┘
此策略在保证跨机架容灾(机架故障数据不丢失)的同时,减少跨机架写入带宽消耗。
3.5 HDFS 数据读写流程
写入流程:
Client → NameNode(请求写入)
← NameNode(返回 DataNode 列表,组成 Pipeline)
Client → DataNode1 → DataNode2 → DataNode3(流水线写入)
← DataNode(ACK 确认)
Client → NameNode(通知写入完成,更新元数据)
读取流程:
Client → NameNode(请求文件块位置)
← NameNode(返回各 Block 的 DataNode 列表)
Client → 最近的 DataNode(按就近原则直接读取数据块)
3.6 HDFS 容错机制
- 心跳检测:DataNode 每 3 秒发送一次心跳,超时(默认 10 分钟)则认为节点宕机
- 自动重复制:节点故障导致某块副本数不足时,NameNode 自动触发重新复制
- 数据完整性校验:客户端写入数据时记录 CRC 校验码,读取时验证
- Trash 回收站 :删除的文件默认移入
.Trash目录,支持恢复
4. MapReduce 详解
4.1 MapReduce 编程模型
MapReduce 将大规模数据处理问题分解为两个函数式操作:
输入数据(大文件)
│
▼
┌─────────────┐
│ InputFormat │ → 将输入分割为多个 InputSplit
└──────┬──────┘
│ 多个 InputSplit 并行处理
▼
┌─────────────┐
│ Map 阶段 │ → 对每条输入记录执行 map() 函数
│ │ 输出:(key, value) 中间结果
└──────┬──────┘
│
▼
┌─────────────┐
│ Shuffle & │ → 按 key 排序、分组,传输到对应 Reducer
│ Sort │
└──────┬──────┘
│
▼
┌─────────────┐
│ Reduce 阶段 │ → 对相同 key 的所有 value 执行 reduce() 函数
│ │ 输出最终结果
└──────┬──────┘
│
▼
输出到 HDFS
4.2 MapReduce 工作原理详解
Map 阶段:
- 将 HDFS 上的数据块作为输入,每个块对应一个 InputSplit
- 每个 InputSplit 由一个 Map Task 处理
- Map 函数读取
<key, value>对,转换为中间<key, value>对 - 中间结果写入本地磁盘(不是 HDFS)
Shuffle & Sort 阶段(框架自动完成):
- 将 Map 输出的中间结果按 key 进行哈希分区,分配到各 Reducer
- 对每个 Reducer 接收到的数据按 key 排序
- 将相同 key 的所有 value 合并为列表
Reduce 阶段:
- 每个 Reduce Task 接收某些 key 的所有
<key, [values]>对 - 执行 reduce() 函数,汇聚计算,输出最终结果
- 结果写回 HDFS
4.3 MapReduce 关键概念
| 概念 | 说明 |
|---|---|
| Job | 用户提交的完整 MapReduce 作业 |
| Task | Job 的最小执行单元,分为 MapTask 和 ReduceTask |
| InputSplit | 逻辑上的输入分片,每个 Split 对应一个 MapTask |
| RecordReader | 将 InputSplit 解析为 <key, value> 记录 |
| Combiner | 在 Map 端的本地 Reducer,减少 Shuffle 数据量(可选) |
| Partitioner | 决定 Map 输出的中间结果分配到哪个 Reducer |
| OutputFormat | 控制最终结果写入 HDFS 的格式 |
| Counter | 统计 Job 运行过程中的各项指标 |
4.4 Combiner 优化
Combiner 是一种可选的本地聚合优化,在 Map 任务完成后、数据发往 Reducer 之前,在本地先做一次归并,显著减少网络传输量。
不用 Combiner:
Map1: (hello,1)(world,1)(hello,1) → Reducer: hello=[1,1,1]
使用 Combiner:
Map1: (hello,2)(world,1) → Reducer: hello=[2,1] (网络传输减少)
注意:Combiner 只适用于满足交换律和结合律的聚合操作(如求和、计数),不适用于求平均值等操作。
5. YARN 详解
5.1 YARN 的由来
Hadoop 1.0 中,JobTracker 同时负责资源管理和作业调度,存在严重问题:
- 扩展性差:JobTracker 内存中维护所有 Task 信息,节点超过 4000 时成为瓶颈
- 可靠性差:JobTracker 单点故障导致所有作业失败
- 资源利用率低:MapReduce slot 概念过于粗糙,无法感知 CPU/内存实际使用量
- 不支持其他框架:只能运行 MapReduce,Spark 等其他框架无法在集群上运行
YARN 在 Hadoop 2.0 中引入,将资源管理与作业调度彻底解耦。
5.2 YARN 架构
┌──────────────────────────────────────────────────────────┐
│ ResourceManager(全局主节点) │
│ ┌─────────────────────┐ ┌──────────────────────────┐ │
│ │ Scheduler(调度器) │ │ ApplicationsManager(AM管│ │
│ │ (FIFO/Capacity/Fair)│ │ 理器) │ │
│ └─────────────────────┘ └──────────────────────────┘ │
└──────────────────────────────┬───────────────────────────┘
│
┌────────────────────┼──────────────────┐
│ │ │
┌──────▼──────┐ ┌──────▼──────┐ ┌──────▼──────┐
│ NodeManager │ │ NodeManager │ │ NodeManager │
│ (节点1) │ │ (节点2) │ │ (节点3) │
│ ┌─────────┐ │ │ ┌─────────┐ │ │ ┌─────────┐ │
│ │Container│ │ │ │Container│ │ │ │Container│ │
│ │ (AM) │ │ │ │(Map Task)│ │ │ │(Reduce) │ │
│ └─────────┘ │ │ └─────────┘ │ │ └─────────┘ │
└─────────────┘ └─────────────┘ └─────────────┘
ResourceManager(RM)
- 全局唯一的资源管理主节点
- 包含两个核心组件:
- Scheduler(调度器):将集群资源按策略分配给各应用,不负责监控任务
- ApplicationsManager(ASM):负责接受 Job 提交、分配 Container 启动 ApplicationMaster、监控 AM 并在失败时重启
NodeManager(NM)
- 每台工作节点上运行一个
- 管理本节点的 Container(封装了 CPU、内存等资源的抽象单元)
- 监控 Container 的资源使用情况,向 ResourceManager 汇报心跳
ApplicationMaster(AM)
- 每个应用(Job)对应一个 AM,在某个 Container 中运行
- 向 ResourceManager 申请资源(Container)
- 与 NodeManager 协作启动任务
- 监控任务执行进度,处理任务失败重试
5.3 YARN 作业提交流程
① 客户端提交 Job → ResourceManager
② ResourceManager 分配 Container → 启动 ApplicationMaster
③ ApplicationMaster 向 ResourceManager 申请运行任务所需的 Container 资源
④ ResourceManager 分配 Container 列表给 ApplicationMaster
⑤ ApplicationMaster 通知 NodeManager 在对应 Container 中启动 MapTask / ReduceTask
⑥ Task 运行,定期向 ApplicationMaster 汇报进度
⑦ Job 完成,ApplicationMaster 向 ResourceManager 注销并释放资源
5.4 YARN 调度器
| 调度器 | 特点 | 适用场景 |
|---|---|---|
| FIFO Scheduler | 先进先出,简单但大作业会阻塞小作业 | 仅用于学习/测试 |
| Capacity Scheduler | 多队列,每个队列保证最小资源容量,默认调度器 | 多租户企业集群 |
| Fair Scheduler | 所有 Job 公平共享资源,小作业响应快 | 混合负载集群 |
6. Hadoop 生态系统
Hadoop 本身是存储和计算的基础设施,围绕它形成了一个丰富的生态系统:
数据可视化层
┌──────────────────┐
│ Hue / Tableau │
└────────┬─────────┘
│
┌──────────────┼──────────────────┐
│ │ │
数据查询层 数据处理层 机器学习层
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Hive / Impala│ │ MapReduce │ │ Mahout │
│ Pig │ │ Spark │ │ MLlib(Spark)│
└──────────────┘ │ Tez │ └──────────────┘
└──────────────┘
│
┌──────────────┼──────────────────┐
│ │ │
NoSQL数据库 数据导入层 工作流调度
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ HBase │ │ Sqoop(RDBMS) │ │ Oozie │
│ Cassandra │ │ Flume(日志)│ │ Azkaban │
└──────────────┘ │ Kafka │ └──────────────┘
└──────────────┘
│
┌──────────────┼──────────────────┐
│ │
资源管理层 协调服务层
┌──────────────────┐ ┌──────────────────┐
│ YARN │ │ ZooKeeper │
└──────────────────┘ └──────────────────┘
│
┌────────┴─────────┐
│ HDFS │
└──────────────────┘
主要生态组件说明
| 组件 | 类型 | 核心功能 |
|---|---|---|
| Apache Hive | SQL 查询引擎 | 将 HQL(类 SQL)查询翻译为 MapReduce/Tez/Spark 作业,适合数据仓库场景 |
| Apache Spark | 内存计算引擎 | 基于内存的高速计算,支持批处理、流处理、SQL、机器学习,比 MapReduce 快 10-100x |
| Apache HBase | 列式 NoSQL 数据库 | 基于 HDFS 的分布式 NoSQL 数据库,支持实时读写,适合稀疏大表 |
| Apache Pig | 数据流脚本工具 | 用 Pig Latin 脚本描述数据流,自动转换为 MapReduce |
| Apache Sqoop | 关系型数据库导入导出 | 在 HDFS/Hive/HBase 与传统 RDBMS(MySQL、Oracle)之间传输数据 |
| Apache Flume | 日志数据采集 | 分布式、可靠的日志数据收集、聚合系统 |
| Apache Kafka | 消息队列/流平台 | 高吞吐量分布式消息系统,常用于实时数据管道 |
| Apache ZooKeeper | 分布式协调服务 | 提供配置管理、命名服务、分布式锁、选主等协调功能 |
| Apache Oozie | 工作流调度 | 定义和调度 Hadoop 作业工作流(DAG) |
| Apache Mahout | 机器学习库 | 提供分布式机器学习算法(聚类、分类、推荐) |
| Apache Tez | DAG 计算引擎 | 基于 YARN 的 DAG 计算框架,比 MapReduce 更灵活高效,Hive 常用其作为执行引擎 |
| Apache Ambari | 集群管理工具 | Web 界面一站式管理、配置、监控 Hadoop 集群 |
7. 安装与环境配置
7.1 系统要求
| 组件 | 要求 |
|---|---|
| 操作系统 | GNU/Linux(推荐 Ubuntu 20.04+、CentOS 7+) |
| Java | JDK 8 或 JDK 11(推荐),需设置 JAVA_HOME |
| SSH | 需安装 OpenSSH,配置免密登录 |
| 内存 | 开发测试:≥ 4GB;生产环境:≥ 64GB |
| 磁盘 | 根据数据量,数据节点建议 JBOD 多块大容量磁盘 |
7.2 单节点(伪分布式)安装
第一步:安装 Java
bash
# Ubuntu/Debian
sudo apt update
sudo apt install -y openjdk-11-jdk
# CentOS/RHEL
sudo yum install -y java-11-openjdk-devel
# 验证
java -version
# 获取 JAVA_HOME 路径
readlink -f $(which java) | sed 's|/bin/java||'
第二步:创建 Hadoop 用户(可选但推荐)
bash
sudo addgroup hadoop
sudo adduser --ingroup hadoop hduser
sudo usermod -aG sudo hduser
su - hduser
第三步:配置 SSH 免密登录
bash
# 生成 SSH 密钥对
ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa
# 将公钥加入授权列表
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
chmod 0600 ~/.ssh/authorized_keys
# 测试免密登录
ssh localhost
第四步:下载并解压 Hadoop
bash
# 下载(以 3.3.6 为例,请从 https://hadoop.apache.org/releases.html 获取最新版本)
wget https://downloads.apache.org/hadoop/common/hadoop-3.3.6/hadoop-3.3.6.tar.gz
tar -xzf hadoop-3.3.6.tar.gz
sudo mv hadoop-3.3.6 /usr/local/hadoop
第五步:配置环境变量
编辑 ~/.bashrc 或 /etc/profile,添加:
bash
export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
export HADOOP_HOME=/usr/local/hadoop
export HADOOP_INSTALL=$HADOOP_HOME
export HADOOP_MAPRED_HOME=$HADOOP_HOME
export HADOOP_COMMON_HOME=$HADOOP_HOME
export HADOOP_HDFS_HOME=$HADOOP_HOME
export HADOOP_YARN_HOME=$HADOOP_HOME
export HADOOP_COMMON_LIB_NATIVE_DIR=$HADOOP_HOME/lib/native
export PATH=$PATH:$HADOOP_HOME/sbin:$HADOOP_HOME/bin
export HADOOP_OPTS="-Djava.library.path=$HADOOP_HOME/lib/native"
bash
source ~/.bashrc
hadoop version # 验证
第六步:配置 hadoop-env.sh
bash
vim /usr/local/hadoop/etc/hadoop/hadoop-env.sh
# 添加以下内容
export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
第七步:配置核心 XML 文件
core-site.xml(指定 HDFS 地址):
xml
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://localhost:9000</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/usr/local/hadoop/tmp</value>
</property>
</configuration>
hdfs-site.xml(配置 HDFS 参数):
xml
<configuration>
<property>
<name>dfs.replication</name>
<value>1</value> <!-- 伪分布式只有一个节点,副本数设为 1 -->
</property>
<property>
<name>dfs.namenode.name.dir</name>
<value>file:///usr/local/hadoop/data/namenode</value>
</property>
<property>
<name>dfs.datanode.data.dir</name>
<value>file:///usr/local/hadoop/data/datanode</value>
</property>
</configuration>
mapred-site.xml(使用 YARN 作为 MapReduce 执行框架):
xml
<configuration>
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<property>
<name>mapreduce.application.classpath</name>
<value>$HADOOP_MAPRED_HOME/share/hadoop/mapreduce/*:$HADOOP_MAPRED_HOME/share/hadoop/mapreduce/lib/*</value>
</property>
</configuration>
yarn-site.xml(YARN 配置):
xml
<configuration>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<property>
<name>yarn.nodemanager.env-whitelist</name>
<value>JAVA_HOME,HADOOP_COMMON_HOME,HADOOP_HDFS_HOME,HADOOP_CONF_DIR,CLASSPATH_PREPEND_DISTCACHE,HADOOP_YARN_HOME,HADOOP_HOME,PATH,LANG,TZ,HADOOP_MAPRED_HOME</value>
</property>
</configuration>
第八步:创建目录并格式化 NameNode
bash
# 创建所需目录
mkdir -p /usr/local/hadoop/data/namenode
mkdir -p /usr/local/hadoop/data/datanode
mkdir -p /usr/local/hadoop/tmp
# ⚠️ 首次运行必须格式化 NameNode(只需执行一次!)
hdfs namenode -format
警告 :
hdfs namenode -format会清空 HDFS 上所有数据,只在初次搭建时执行一次。
第九步:启动 Hadoop
bash
# 启动 HDFS
start-dfs.sh
# 启动 YARN
start-yarn.sh
# 或者一键启动所有组件
start-all.sh
# 验证进程(应看到以下进程)
jps
# 输出应包含:
# NameNode
# DataNode
# SecondaryNameNode
# ResourceManager
# NodeManager
第十步:验证安装
bash
# 创建 HDFS 用户目录
hdfs dfs -mkdir -p /user/hduser
# 访问 Web UI
# NameNode: http://localhost:9870
# YARN: http://localhost:8088
# JobHistory: http://localhost:19888
停止 Hadoop
bash
stop-all.sh
# 或分别停止
stop-dfs.sh
stop-yarn.sh
7.3 多节点集群搭建
假设集群规划:
| 主机名 | IP | 角色 |
|---|---|---|
| master | 192.168.1.100 | NameNode + ResourceManager |
| slave1 | 192.168.1.101 | DataNode + NodeManager |
| slave2 | 192.168.1.102 | DataNode + NodeManager |
步骤一:所有节点配置 /etc/hosts
在所有节点的 /etc/hosts 中添加:
192.168.1.100 master
192.168.1.101 slave1
192.168.1.102 slave2
步骤二:配置 SSH 免密登录(master → 所有节点)
bash
# 在 master 上生成密钥
ssh-keygen -t rsa -P ''
# 将公钥复制到所有节点(包括 master 自身)
ssh-copy-id hduser@master
ssh-copy-id hduser@slave1
ssh-copy-id hduser@slave2
步骤三:所有节点安装 Java 和 Hadoop(路径保持一致)
步骤四:修改 master 的配置文件
core-site.xml:
xml
<property>
<name>fs.defaultFS</name>
<value>hdfs://master:9000</value>
</property>
hdfs-site.xml:
xml
<property>
<name>dfs.replication</name>
<value>2</value> <!-- 副本数通常设为 2~3 -->
</property>
workers 文件 ($HADOOP_HOME/etc/hadoop/workers):
slave1
slave2
步骤五:将配置同步到所有节点
bash
scp -r /usr/local/hadoop/etc/hadoop/* hduser@slave1:/usr/local/hadoop/etc/hadoop/
scp -r /usr/local/hadoop/etc/hadoop/* hduser@slave2:/usr/local/hadoop/etc/hadoop/
步骤六:格式化 NameNode 并启动
bash
# 仅在 master 执行
hdfs namenode -format
start-dfs.sh
start-yarn.sh
# 验证(所有节点应有对应进程)
# master: NameNode, SecondaryNameNode, ResourceManager
# slaves: DataNode, NodeManager
8. HDFS 常用命令
HDFS 文件系统命令格式:hdfs dfs -<命令> 或 hadoop fs -<命令>
8.1 目录操作
bash
# 列出目录内容
hdfs dfs -ls /
hdfs dfs -ls -R /user # 递归列出
# 创建目录
hdfs dfs -mkdir /data
hdfs dfs -mkdir -p /user/hduser/input # 递归创建
# 删除目录
hdfs dfs -rm -r /data/tmp # 删除目录(-r 递归)
hdfs dfs -rm -r -skipTrash /data/tmp # 跳过回收站直接删除
8.2 文件操作
bash
# 上传本地文件到 HDFS
hdfs dfs -put localfile.txt /user/hduser/input/
hdfs dfs -copyFromLocal localfile.txt /user/hduser/
hdfs dfs -moveFromLocal localfile.txt /user/hduser/ # 移动(本地文件被删除)
# 从 HDFS 下载到本地
hdfs dfs -get /user/hduser/output/part-r-00000 ./output.txt
hdfs dfs -copyToLocal /user/hduser/output/ ./
hdfs dfs -getmerge /user/hduser/output/ ./merged.txt # 合并多个文件下载
# 查看 HDFS 文件内容
hdfs dfs -cat /user/hduser/input/file.txt
hdfs dfs -tail /user/hduser/input/file.txt # 查看最后 1KB
# 文件复制和移动
hdfs dfs -cp /user/hduser/input/a.txt /user/hduser/backup/
hdfs dfs -mv /user/hduser/tmp/ /user/hduser/archive/
# 统计文件大小
hdfs dfs -du -h /user/hduser # 显示各文件大小(人类可读)
hdfs dfs -du -s -h /user/hduser # 仅显示汇总大小
hdfs dfs -count /user/hduser # 目录数、文件数、字节数
8.3 HDFS 管理命令
bash
# 查看 HDFS 整体状态
hdfs dfsadmin -report
# 安全模式操作(Safe Mode)
hdfs dfsadmin -safemode get # 查看安全模式状态
hdfs dfsadmin -safemode enter # 进入安全模式(只读)
hdfs dfsadmin -safemode leave # 退出安全模式
# 数据均衡(Balancer)
hdfs balancer -threshold 10 # 启动均衡器,不均衡度阈值 10%
# 检查文件系统健康状况
hdfs fsck / # 检查整个文件系统
hdfs fsck /user/hduser -files -blocks # 检查指定路径,显示块信息
# 查看 block 信息
hdfs fsck /user/hduser/file.txt -files -blocks -locations
# 更改副本因子
hdfs dfs -setrep -w 3 /user/hduser/important.txt # 设置副本数为 3
# 查看 NameNode/DataNode 信息
hdfs dfsadmin -printTopology # 查看集群拓扑
8.4 权限管理
bash
# 修改文件权限(与 Linux chmod 语法相同)
hdfs dfs -chmod 755 /user/hduser/data
hdfs dfs -chmod -R 755 /user/hduser/ # 递归修改
# 修改所有者
hdfs dfs -chown hduser:hadoop /user/hduser/data
hdfs dfs -chown -R hduser:hadoop /user/hduser/
9. MapReduce 编程实战(WordCount)
9.1 经典 WordCount 示例(Java)
这是 Hadoop 的 "Hello World",统计文本文件中每个单词的出现次数。
java
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import java.io.IOException;
import java.util.StringTokenizer;
public class WordCount {
/**
* Mapper:读取每行文本,输出 <word, 1> 键值对
*/
public static class TokenizerMapper
extends Mapper<Object, Text, Text, IntWritable> {
private final static IntWritable one = new IntWritable(1);
private Text word = new Text();
@Override
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); // 输出 <word, 1>
}
}
}
/**
* Reducer:汇总相同单词的计数
*/
public static class IntSumReducer
extends Reducer<Text, IntWritable, Text, IntWritable> {
private IntWritable result = new IntWritable();
@Override
public void reduce(Text key, Iterable<IntWritable> values, Context context)
throws IOException, InterruptedException {
int sum = 0;
for (IntWritable val : values) {
sum += val.get(); // 求和
}
result.set(sum);
context.write(key, result); // 输出 <word, count>
}
}
public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
Job job = Job.getInstance(conf, "word count");
job.setJarByClass(WordCount.class);
job.setMapperClass(TokenizerMapper.class);
job.setCombinerClass(IntSumReducer.class); // 使用 Combiner 优化
job.setReducerClass(IntSumReducer.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);
}
}
9.2 编译和运行
bash
# 1. 编译(确保已安装 Maven 或手动引入 Hadoop JAR)
javac -classpath $(hadoop classpath) WordCount.java
jar cf wordcount.jar WordCount*.class
# 2. 准备输入数据
echo "hello world hello hadoop world" > input.txt
hdfs dfs -mkdir -p /user/hduser/wordcount/input
hdfs dfs -put input.txt /user/hduser/wordcount/input/
# 3. 运行 MapReduce Job
hadoop jar wordcount.jar WordCount \
/user/hduser/wordcount/input \
/user/hduser/wordcount/output
# 4. 查看结果
hdfs dfs -cat /user/hduser/wordcount/output/part-r-00000
# 输出:
# hadoop 1
# hello 2
# world 2
9.3 使用内置示例
Hadoop 自带多个示例程序,可直接运行:
bash
# 查看所有内置示例
hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-*.jar
# 运行 WordCount
hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-*.jar \
wordcount /user/hduser/input /user/hduser/output
# 运行 Pi(计算圆周率,用于测试集群是否正常工作)
hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-*.jar \
pi 10 100
# 运行 TeraSort(大数据排序性能测试)
# 先生成测试数据
hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-*.jar \
teragen 10000 /terasort/input
# 执行排序
hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-*.jar \
terasort /terasort/input /terasort/output
10. 核心配置文件详解
所有配置文件位于 $HADOOP_HOME/etc/hadoop/。
10.1 core-site.xml
xml
<configuration>
<!-- HDFS 默认地址 -->
<property>
<name>fs.defaultFS</name>
<value>hdfs://master:9000</value>
</property>
<!-- Hadoop 临时目录 -->
<property>
<name>hadoop.tmp.dir</name>
<value>/data/hadoop/tmp</value>
</property>
<!-- I/O 缓冲区大小(默认 4KB,建议 128KB) -->
<property>
<name>io.file.buffer.size</name>
<value>131072</value>
</property>
<!-- 回收站文件保留时间(分钟,0 表示禁用) -->
<property>
<name>fs.trash.interval</name>
<value>1440</value>
</property>
</configuration>
10.2 hdfs-site.xml
xml
<configuration>
<!-- 数据副本数 -->
<property>
<name>dfs.replication</name>
<value>3</value>
</property>
<!-- 数据块大小(128MB) -->
<property>
<name>dfs.blocksize</name>
<value>134217728</value>
</property>
<!-- NameNode 元数据目录 -->
<property>
<name>dfs.namenode.name.dir</name>
<value>file:///data/hadoop/dfs/name</value>
</property>
<!-- DataNode 数据目录(可指定多个磁盘) -->
<property>
<name>dfs.datanode.data.dir</name>
<value>file:///data/disk1/dfs/data,file:///data/disk2/dfs/data</value>
</property>
<!-- NameNode Web UI 端口 -->
<property>
<name>dfs.namenode.http-address</name>
<value>master:9870</value>
</property>
<!-- 是否允许修改权限(生产环境建议 true) -->
<property>
<name>dfs.permissions.enabled</name>
<value>true</value>
</property>
<!-- 短路读取(DataNode 和客户端在同一节点时直接读本地文件) -->
<property>
<name>dfs.client.read.shortcircuit</name>
<value>true</value>
</property>
</configuration>
10.3 mapred-site.xml
xml
<configuration>
<!-- 使用 YARN 执行引擎 -->
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<!-- Map 任务内存(MB) -->
<property>
<name>mapreduce.map.memory.mb</name>
<value>1024</value>
</property>
<!-- Reduce 任务内存(MB) -->
<property>
<name>mapreduce.reduce.memory.mb</name>
<value>2048</value>
</property>
<!-- Map 任务 JVM 堆大小 -->
<property>
<name>mapreduce.map.java.opts</name>
<value>-Xmx768m</value>
</property>
<!-- Reduce 任务 JVM 堆大小 -->
<property>
<name>mapreduce.reduce.java.opts</name>
<value>-Xmx1536m</value>
</property>
<!-- Shuffle 压缩(减少网络传输量) -->
<property>
<name>mapreduce.map.output.compress</name>
<value>true</value>
</property>
<property>
<name>mapreduce.map.output.compress.codec</name>
<value>org.apache.hadoop.io.compress.SnappyCodec</value>
</property>
<!-- JobHistory Server 地址 -->
<property>
<name>mapreduce.jobhistory.address</name>
<value>master:10020</value>
</property>
</configuration>
10.4 yarn-site.xml
xml
<configuration>
<!-- ResourceManager 主机 -->
<property>
<name>yarn.resourcemanager.hostname</name>
<value>master</value>
</property>
<!-- NodeManager 附属服务(MapReduce 必须) -->
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<!-- 每个节点可用内存(MB,建议为物理内存的 80%) -->
<property>
<name>yarn.nodemanager.resource.memory-mb</name>
<value>8192</value>
</property>
<!-- 每个节点可用 CPU 核数 -->
<property>
<name>yarn.nodemanager.resource.cpu-vcores</name>
<value>4</value>
</property>
<!-- 单个 Container 最小/最大内存 -->
<property>
<name>yarn.scheduler.minimum-allocation-mb</name>
<value>512</value>
</property>
<property>
<name>yarn.scheduler.maximum-allocation-mb</name>
<value>4096</value>
</property>
<!-- 启用日志聚合(将各节点日志集中到 HDFS) -->
<property>
<name>yarn.log-aggregation-enable</name>
<value>true</value>
</property>
<property>
<name>yarn.nodemanager.remote-app-log-dir</name>
<value>/logs/yarn</value>
</property>
</configuration>
11. 集群监控与管理
11.1 Web UI 监控页面
| 服务 | 默认 URL | 功能 |
|---|---|---|
| NameNode Web UI | http://master:9870 | HDFS 状态、文件浏览、DataNode 列表 |
| YARN ResourceManager | http://master:8088 | 作业队列、运行中 Application、节点状态 |
| MapReduce JobHistory | http://master:19888 | 历史作业查询和日志 |
| DataNode Web UI | http://datanode:9864 | 单个 DataNode 存储状态 |
| NodeManager Web UI | http://nodenode:8042 | 单个 NodeManager 容器状态 |
11.2 常用管理命令
bash
# 查看集群报告
hdfs dfsadmin -report
# 查看活跃节点
yarn node -list
# 查看运行中的应用
yarn application -list
# 杀死应用
yarn application -kill application_1234567890_0001
# 查看应用日志
yarn logs -applicationId application_1234567890_0001
# 检查队列
yarn queue -status default
# 查看 HDFS 配额
hdfs dfsadmin -refreshNodes
11.3 使用 jps 验证进程
bash
jps
# 正常输出(Master 节点):
# 1234 NameNode
# 1456 SecondaryNameNode
# 1678 ResourceManager
# 2345 Jps
# 正常输出(Slave 节点):
# 2345 DataNode
# 2567 NodeManager
# 2789 Jps
12. 高可用(HA)方案
12.1 HDFS NameNode HA
生产环境中 NameNode 是单点故障,Hadoop 2.0+ 支持 NameNode HA:
架构:Active NameNode + Standby NameNode
┌──────────────┐ ┌──────────────┐
│ Active NN │ │ Standby NN │
└──────┬───────┘ └──────┬───────┘
│ 写 editlog │ 读 editlog
▼ ▼
┌──────────────────────────────────────┐
│ JournalNode 集群(>=3 节点) │
│ JN1 | JN2 | JN3 │
└──────────────────────────────────────┘
│
┌────────▼──────────────────────────────┐
│ ZooKeeper 集群(自动切换用) │
└───────────────────────────────────────┘
配置要点:
- 至少 3 个 JournalNode(奇数个)保证 editlog 高可用
- 使用 ZooKeeper 实现 Active NN 自动故障切换(ZKFC:ZooKeeper Failover Controller)
- Standby NN 实时同步元数据,接管时无需格式化
xml
<!-- hdfs-site.xml 中 HA 相关配置 -->
<property>
<name>dfs.nameservices</name>
<value>mycluster</value>
</property>
<property>
<name>dfs.ha.namenodes.mycluster</name>
<value>nn1,nn2</value>
</property>
<property>
<name>dfs.namenode.rpc-address.mycluster.nn1</name>
<value>master1:8020</value>
</property>
<property>
<name>dfs.namenode.rpc-address.mycluster.nn2</name>
<value>master2:8020</value>
</property>
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
12.2 YARN ResourceManager HA
xml
<!-- yarn-site.xml 中 RM HA 配置 -->
<property>
<name>yarn.resourcemanager.ha.enabled</name>
<value>true</value>
</property>
<property>
<name>yarn.resourcemanager.cluster-id</name>
<value>mycluster</value>
</property>
<property>
<name>yarn.resourcemanager.ha.rm-ids</name>
<value>rm1,rm2</value>
</property>
13. 性能调优
13.1 HDFS 调优
bash
# 1. 调整块大小(大文件用 256MB,减少元数据压力)
<property>
<name>dfs.blocksize</name>
<value>268435456</value> <!-- 256MB -->
</property>
# 2. 增大 NameNode JVM 堆(每百万个文件/块约需 1GB)
export HDFS_NAMENODE_OPTS="-Xms20g -Xmx20g"
# 3. 配置多磁盘(JBOD 方式提升 I/O 并发)
<property>
<name>dfs.datanode.data.dir</name>
<value>/disk1/data,/disk2/data,/disk3/data,/disk4/data</value>
</property>
# 4. 开启短路读取,减少本地读取网络开销
<property>
<name>dfs.client.read.shortcircuit</name>
<value>true</value>
</property>
13.2 MapReduce 调优
xml
<!-- 减少 Reducer 数量(数据量不大时) -->
<property>
<name>mapreduce.job.reduces</name>
<value>10</value>
</property>
<!-- 开启推测执行(处理慢节点) -->
<property>
<name>mapreduce.map.speculative</name>
<value>true</value>
</property>
<property>
<name>mapreduce.reduce.speculative</name>
<value>true</value>
</property>
<!-- Shuffle 阶段内存调优 -->
<property>
<name>mapreduce.task.io.sort.mb</name>
<value>512</value> <!-- 排序缓冲区大小 -->
</property>
<property>
<name>mapreduce.task.io.sort.factor</name>
<value>100</value> <!-- 归并时最大并发流数 -->
</property>
13.3 YARN 调优
xml
<!-- 开启内存严格限制(防止内存不足节点崩溃) -->
<property>
<name>yarn.nodemanager.pmem-check-enabled</name>
<value>true</value>
</property>
<property>
<name>yarn.nodemanager.vmem-check-enabled</name>
<value>false</value> <!-- 关闭虚拟内存检查,避免误杀 -->
</property>
<!-- Container CPU 调度策略 -->
<property>
<name>yarn.nodemanager.resource.detect-hardware-capabilities</name>
<value>true</value>
</property>
13.4 常见调优方向汇总
| 问题 | 调优方法 |
|---|---|
| Map 任务数过多(小文件问题) | 使用 CombineInputFormat 合并小文件;预处理用 Hive/Spark 合并 |
| Shuffle 阶段慢 | 开启 Snappy 压缩、增大排序缓冲区 |
| Reduce 数据倾斜 | 自定义 Partitioner;加随机前缀后二次聚合 |
| NameNode 内存不足 | 增大 JVM 堆;使用 HDFS Federation 水平扩展 NameNode |
| 磁盘 I/O 瓶颈 | 配置多磁盘;开启 HDFS 压缩 |
| 推测执行导致重复计算 | 对幂等操作开启推测,对非幂等操作关闭 |
14. Hadoop 3.x 新特性
14.1 纠删码(Erasure Coding)
Hadoop 3.x 引入纠删码,是对 3 副本策略的重大革新:
| 方案 | 存储开销 | 容错能力 |
|---|---|---|
| 3 副本 | 200% 额外存储(3x) | 可容 2 个节点故障 |
| EC(6+3 Reed-Solomon) | 50% 额外存储 | 可容 3 个节点故障 |
纠删码将数据分为 6 个数据块 + 3 个奇偶校验块,总开销大幅降低,适合冷数据存储。
bash
# 查看支持的纠删码策略
hdfs ec -listPolicies
# 设置目录的纠删码策略
hdfs ec -setPolicy -path /cold-data -policy RS-6-3-1024k
14.2 多 NameNode Federation 升级
Hadoop 3.x 支持在单个集群内运行多个 NameNode(Federation),每个 NameNode 管理一个命名空间,通过 Router-Based Federation(RBF) 提供统一入口,解决超大集群 NameNode 内存瓶颈。
14.3 其他重要改进
- 最低 Java 版本提升至 Java 8
- Intra-datanode 均衡器:平衡单个 DataNode 内多块磁盘的数据分布
- YARN 时间线服务 v2:支持更大规模的 Application 历史记录
- 默认端口变更:
| 服务 | Hadoop 2.x 端口 | Hadoop 3.x 端口 |
|---|---|---|
| NameNode HTTP | 50070 | 9870 |
| DataNode HTTP | 50075 | 9864 |
| SecondaryNameNode | 50090 | 9868 |
| ResourceManager | 8088 | 8088(不变) |
- 支持 GPU 和 FPGA 调度(通过 YARN 的 Generic Resource(FPGA/GPU)机制)
- HDFS 路由器联邦(Router-Based Federation):令 HDFS 可横向扩展
15. 常见问题与排查
15.1 NameNode 启动后立即进入安全模式
原因 :DataNode 尚未完全注册,数据块副本数未满足最低要求。
解决:等待 DataNode 启动完成(通常 30~60 秒后自动退出),或手动退出:
bash
hdfs dfsadmin -safemode leave
15.2 DataNode 无法启动
原因 :常见于重复执行了 hdfs namenode -format,导致 NameNode 和 DataNode 的 ClusterID 不一致。
解决:
bash
# 查看 NameNode 的 clusterID
cat /usr/local/hadoop/data/namenode/current/VERSION
# 修改 DataNode 的 VERSION 文件中的 clusterID 与 NameNode 一致
vim /usr/local/hadoop/data/datanode/current/VERSION
# 或者删除 DataNode 数据目录,重新同步
rm -rf /usr/local/hadoop/data/datanode/*
start-dfs.sh
15.3 HDFS 文件上传失败:"No space left"
bash
# 检查 HDFS 使用情况
hdfs dfs -df -h /
hdfs dfsadmin -report
# 如果 HDFS 配额不足,临时增加配额
hdfs dfsadmin -setSpaceQuota 500g /user/hduser
15.4 MapReduce 作业卡在 Map 0% 不动
排查步骤:
bash
# 1. 查看 YARN 作业日志
yarn logs -applicationId <application_id>
# 2. 检查 ResourceManager UI(http://master:8088)查看作业状态
# 3. 检查 NodeManager 是否正常运行
yarn node -list
# 4. 检查内存配置是否合理(Container 申请内存超过节点上限会一直等待)
15.5 连接 NameNode 拒绝
bash
# 确认防火墙规则
sudo ufw allow 9000
sudo ufw allow 9870
# 检查 NameNode 进程
jps | grep NameNode
# 查看 NameNode 日志
tail -f $HADOOP_HOME/logs/hadoop-*-namenode-*.log
15.6 数据倾斜(Reduce 阶段某个 Task 运行远慢于其他)
症状 :Map 100%,Reduce 停留在 99%,只有一两个 Task 仍在运行。
解决方案:
- 自定义 Partitioner,让 key 均匀分布
- 对热点 key 添加随机前缀,二次 MapReduce 聚合
- 使用 Spark 替代 MapReduce(更好地处理数据倾斜)
16. 与现代大数据技术的对比
16.1 Hadoop MapReduce vs Apache Spark
| 对比维度 | Hadoop MapReduce | Apache Spark |
|---|---|---|
| 计算模式 | 批处理,基于磁盘 | 内存计算,支持批处理/流处理 |
| 处理速度 | 相对慢(磁盘 I/O 为主) | 快 10~100 倍(内存计算) |
| 数据持久化 | 每步结果写 HDFS | 可缓存在内存(RDD/DataFrame) |
| 编程模型 | 仅 Map + Reduce | 丰富的 API:SQL、ML、图计算、流处理 |
| 容错机制 | 任务级重试 | RDD 血缘(Lineage)重算 |
| 适用场景 | 超大规模批量 ETL | 复杂计算、实时分析、机器学习 |
| 资源要求 | 较低(磁盘密集) | 较高(内存密集) |
16.2 Hadoop 在 2024 年的地位
Hadoop 并没有消亡,而是在特定场景中不可替代:
仍在广泛使用的场景:
- 超大规模数据仓库底层存储(HDFS)
- 遗留系统(Legacy Systems)的大数据处理
- 监管合规要求本地化(On-Premise)部署的行业(金融、政府)
- 与 Spark/Hive/Flink 等结合使用,HDFS 作为统一存储层
逐渐被替代的场景:
- 实时计算(Flink、Spark Streaming 替代)
- 云原生存储(AWS S3、Azure ADLS、阿里云 OSS 替代 HDFS)
- 交互式查询(Spark SQL、Presto/Trino 替代 Hive-on-MR)
16.3 Hadoop 与云存储
现代大数据架构趋势是计算存储分离:
传统 Hadoop: 现代云原生架构:
HDFS(存储) ←→ Spark 对象存储(S3/OSS)← → Spark/Flink
同一集群 弹性伸缩,按需付费
附录
A. 官方参考资源
B. 默认端口速查
| 服务 | 端口 | 协议 |
|---|---|---|
| HDFS NameNode RPC | 8020 / 9000 | IPC |
| HDFS NameNode Web UI | 9870 | HTTP |
| HDFS DataNode 数据传输 | 9866 | TCP |
| HDFS DataNode Web UI | 9864 | HTTP |
| HDFS SecondaryNameNode Web UI | 9868 | HTTP |
| YARN ResourceManager Web UI | 8088 | HTTP |
| YARN ResourceManager RPC | 8032 | IPC |
| YARN NodeManager Web UI | 8042 | HTTP |
| MapReduce JobHistory Web UI | 19888 | HTTP |
| MapReduce JobHistory RPC | 10020 | IPC |
C. 关键术语速查
| 术语 | 解释 |
|---|---|
| Block | HDFS 文件的最小存储单元,默认 128MB |
| Replication | 数据块的副本机制,默认 3 份 |
| NameNode | HDFS 主节点,管理元数据 |
| DataNode | HDFS 从节点,存储数据块 |
| YARN | Yet Another Resource Negotiator,集群资源管理器 |
| ResourceManager | YARN 主节点,管理全局资源 |
| NodeManager | YARN 从节点,管理本节点资源 |
| ApplicationMaster | 每个 Job 对应一个,负责任务调度 |
| Container | YARN 封装的资源单元(CPU+内存) |
| InputSplit | Map 任务的逻辑输入分片 |
| Combiner | Map 端的本地聚合,减少 Shuffle 数据量 |
| Shuffle | Map 输出到 Reduce 输入之间的数据传输和排序过程 |
| Speculative Execution | 推测执行,为慢任务启动备份任务 |
| Rack Awareness | 机架感知,优化副本放置和网络流量 |
| Safe Mode | NameNode 只读模式,启动时数据检查阶段 |
| Federation | 多 NameNode 横向扩展方案 |
| Erasure Coding | 纠删码,比 3 副本节省约 50% 存储 |