前哨站/第4章 Hadoop分布式文件系统
第4章 Hadoop分布式文件系统

第4章 Hadoop分布式文件系统

HDFS 为什么这么设计、数据怎么保证不丢、一次读和一次写各自经历了什么。

HDFS副本读写流程

本章学习目标

  • 能说出 HDFS 的设计目标与不足
  • 能画出 HDFS 体系结构(NameNode / DataNode / Client)
  • 能说明副本机制、心跳机制、机架感知与安全模式
  • 能完整描述 HDFS 读流程与写流程
  • 能用命令行和 Java API 操作 HDFS

本章导览

核心内容

4.1

HDFS概述

HDFS(Hadoop Distributed File System)是为"一次写入、多次读取"的超大文件设计的分布式文件系统。

4.1.1

HDFS的设计目标和不足

目标实现方式
超大文件存储文件切块(默认 128MB)+ 多节点存放
硬件容错数据多副本,节点故障自动切换
流式数据访问顺序读为主,高吞吐优于低延迟
简单一致性模型一次写入多次读取,不支持随机修改
  • 不足一:不适合低延迟访问(毫秒级查询请用 HBase)
  • 不足二:不适合大量小文件(NameNode 内存压力)
  • 不足三:不支持多用户并发写入同一文件
4.1.2

HDFS的体系结构

角色职责数量
NameNode管理元数据(目录树、文件与块的映射、块位置)1(HA 下 2)
DataNode实际存储数据块,定期向 NN 汇报块列表多
SecondaryNameNode定期合并 FsImage 与 EditLog(不是备份)1
Client切分文件、与 NN 交互获取块位置、直接读写 DN多
常见误区:SecondaryNameNode 不是 NameNode 的热备,它只做元数据检查点合并。高可用要靠第2章的 NameNode HA(Standby + JournalNode + ZooKeeper)。
4.2

数据错误与恢复

HDFS 假设"硬件一定会坏",所以把容错做进了每个环节。

4.2.1

block损坏处理

  • 写数据时客户端计算校验和,DataNode 存校验和并随块一起保存
  • 读取时客户端比对校验和,不一致说明块损坏
  • 客户端自动向 NameNode 报告坏块,改从其它副本读取
  • NameNode 标记该块副本失效,并从其它副本复制一份补齐
4.2.2

NameNode和DataNode错误处理

  • DataNode 故障:心跳超时(默认 10.5 分钟)判定死亡,副本数不足则自动补副本
  • NameNode 故障:HA 架构下 Standby 通过 ZooKeeper 选举接管;非 HA 需手工恢复 FsImage
  • 元数据安全:通过 <code class="inl">fsimage</code> + <code class="inl">edits</code> 持久化,SecondaryNameNode 定期合并
4.3

HDFS的运行机制

这一节是全章的理论核心,也是笔试高频考点。

机制一句话解释
副本机制每个块默认存 3 份,分布在不同节点/机架
心跳机制DataNode 每 3 秒向 NameNode 汇报,超时判死
机架感知副本按"本机架 1 份 + 异地架 2 份"放置,兼顾性能与容错
Federation多个 NameNode 各管一部分命名空间,解决单 NN 内存瓶颈
HAActive/Standby 双 NN,靠 JournalNode + ZooKeeper 实现秒级切换
安全模式启动时只读校验块,不接收写操作
垃圾回收删除的文件先进 /trash,超时(默认 6 小时)才真正删除
SHELL
# 安全模式相关命令
hdfs dfsadmin -safemode get      # 查看是否在安全模式
hdfs dfsadmin -safemode leave    # 强制退出(块缺失时可临时救急)

# 副本数与机架感知
hdfs dfs -setrep -w 3 /data/a.txt
hdfs dfsadmin -printTopology
4.4

HDFS的工作流程

教材把流程拆成启动、读、写、删除四段,建议背下写流程的七个步骤——面试几乎必问。

4.4.3

HDFS写流程

  • ① Client 调用 create() 向 NameNode 请求创建文件
  • ② NameNode 校验权限与是否已存在,返回可写状态
  • ③ Client 请求第一个 block 的 DataNode 列表
  • ④ 返回的 DataNode 组成 pipeline,Client 开始写第一个节点
  • ⑤ 数据包沿 pipeline 逐级传递并写入磁盘
  • ⑥ 每个节点写完回 ACK,逐级回传
  • ⑦ 文件写完,Client 通知 NameNode 关闭文件(complete)
写流程的关键词:pipeline(管道)、packet(数据包)、ACK 确认。一个节点失败会自动剔除该节点并重建 pipeline。
4.4.2

HDFS读流程

  • ① Client 向 NameNode 请求打开文件
  • ② NameNode 返回该文件所有 block 所在的 DataNode 列表(按距离排序)
  • ③ Client 选择最近的 DataNode 读取数据块
  • ④ 读取完成关闭连接
  • ⑤ 依次读取下一个 block,直到读完

💡 读流程不经过 NameNode 传数据,NameNode 只给"地图",数据直接由 DataNode 到 Client——这是 HDFS 能支撑高吞吐的关键设计。

4.5

HDFS的基本操作

命令行最常用,Java API 是后续 MapReduce 编程的基础。

4.5.1

HDFS命令行操作

命令作用
hdfs dfs -ls /查看目录
hdfs dfs -mkdir -p /a/b递归创建目录
hdfs dfs -put 本地文件 /路径上传(等价 -copyFromLocal)
hdfs dfs -get /路径 本地下载(等价 -copyToLocal)
hdfs dfs -cat /文件查看内容
hdfs dfs -du -h /路径查看大小
hdfs dfs -mv / -cp / -rm -r移动 / 复制 / 删除
hdfs dfs -chmod -R 777 /路径改权限
hdfs dfs -expunge清空回收站
SHELL
hdfs dfs -mkdir -p /data/input
hdfs dfs -put /home/hadoop/w.txt /data/input/
hdfs dfs -ls -h /data/input
hdfs dfs -cat /data/input/w.txt
hdfs dfs -du -h /data
hdfs dfs -rm -r /data/input
4.5.2

HDFS Java API操作

JAVA
Configuration conf = new Configuration();
conf.set("fs.defaultFS", "hdfs://hadoop1:9000");
FileSystem fs = FileSystem.get(conf);

// 上传
fs.copyFromLocalFile(new Path("D:/w.txt"), new Path("/data/input/w.txt"));
// 下载
fs.copyToLocalFile(new Path("/data/input/w.txt"), new Path("D:/out.txt"));
// 判断存在 / 列目录
System.out.println(fs.exists(new Path("/data/input")));
for (FileStatus s : fs.listStatus(new Path("/data"))) {
    System.out.println(s.getPath() + "  " + s.getLen());
}
fs.close();

本章小结

本章先讲 HDFS 的设计目标与不足,再讲体系结构(NameNode/DataNode/SecondaryNameNode/Client),然后系统梳理了副本、心跳、机架感知、Federation、HA、安全模式、垃圾回收七大机制,重点展开读流程与写流程,最后给出命令行与 Java API 两套操作方式。

思考与练习 先自己做,再点开答案

01

HDFS 默认块大小是多少?为什么这么大?

查看参考答案

Hadoop 2.x/3.x 默认为 128MB(1.x 为 64MB)。块大可以降低寻址开销占比,让磁盘传输时间占主导,从而提高吞吐;同时减少 NameNode 需要管理的块数量。

02

SecondaryNameNode 是 NameNode 的备份吗?

查看参考答案

不是。它只负责定期把 NameNode 的 EditLog 合并进 FsImage,减轻 NameNode 启动时的合并压力。NameNode 真正的高可用要靠 HA(Standby NameNode + JournalNode + ZooKeeper)。

03

写一个 200MB 的文件,会切几个块?写流程经过哪些角色?

查看参考答案

按 128MB 切块,200MB = 128MB + 72MB,共 2 个块。流程:Client → NameNode 请求创建与块位置 → 按 pipeline 依次写入 DataNode1→2→3 → 各节点回 ACK → 全部写完通知 NameNode complete。

04

进入安全模式后为什么不能写数据?怎么退出?

查看参考答案

安全模式是 NameNode 启动时校验各 DataNode 块报告的过程,此时 HDFS 只读不写。查看 hdfs dfsadmin -safemode get,正常会自动退出;块缺失导致卡住时可 hdfs dfsadmin -safemode leave(需先确认数据可用)。