HDFS知识笔记

Hadoop HDFS分布式文件系统

一、HDFS 优缺点

HDFS 的设计目标是适配“大数据批处理”场景,因此优缺点具有明显的场景导向性。

1. 优点:适配大数据场景

  • 支持超大规模数据:无论是数据量(PB 级甚至 EB 级)还是文件数量,HDFS 都能通过分布式架构高效承载。
  • 高容错性:默认将数据自动保存 3 个副本,当某个副本因节点故障丢失时,HDFS 会自动从其他副本恢复,无需人工干预。
  • 低成本部署:可构建在廉价的普通服务器上,通过软件层面的容错机制替代昂贵的硬件冗余,降低集群建设成本。

2. 缺点:不适合实时/小文件场景

  • 存储大量小文件效率低
    • 内存开销大:NameNode 需存储所有文件的目录信息和块映射,小文件(如 KB 级)会导致元数据数量暴增,耗尽 NameNode 有限内存。
    • 寻址效率低:小文件的“寻址时间”(定位块位置)会远超过“读取时间”,违背 HDFS“减少寻址、提升传输效率”的设计目标。
  • 不支持并发写入与随机修改
    • 单文件不支持多线程并发写入,避免数据一致性问题。
    • 仅支持“数据追加”(Append),不支持随机修改文件内容(如中间插入、删除数据)。
  • 不支持低延迟访问:HDFS 设计初衷是“批处理”,无法满足毫秒级、秒级的实时数据读写需求(如在线数据库场景)。

二、HDFS 的组成架构

HDFS 采用主从(Master/Slave)架构,核心角色包括 NameNode(主节点)、DataNode(从节点)、Secondary NameNode(辅助节点)和 Client(客户端),各角色职责明确、协同工作。

角色 核心职责 地位
NameNode(NN) 1. 管理 HDFS 名称空间(目录、文件结构);
2. 配置副本策略(如默认 3 副本);
3. 维护数据块与 DataNode 的映射关系;
4. 处理客户端的读写请求(仅元数据层面)
主节点,集群“大脑”,单点(需通过 HA 实现高可用)
DataNode(DN) 1. 存储实际的数据块(Block);
2. 执行数据块的读写操作;
3. 通过心跳向 NameNode 汇报自身状态
从节点,集群“存储节点”,可横向扩展
Secondary NameNode(2NN) 1. 辅助 NN,定期合并 fsimage 和 edits 日志,减轻 NN 负担;
2. 紧急情况下(如 NN 宕机且无 HA),可辅助恢复 NN 元数据
辅助节点,非 NN 备用节点(HA 架构中被 JournalNode 替代)
Client(客户端) 1. 上传文件时切分文件为数据块;
2. 与 NN 交互获取文件位置,与 DN 交互读写数据;
3. 提供 HDFS 管理命令(如格式化 NN、增删文件)
交互入口,非集群节点,可部署在集群内或外部

三、HDFS 写数据流程

HDFS 的写数据流程需协调 Client、NN、DN 三者,核心是“元数据校验→块切分→副本分配→流水线传输→元数据更新”,确保数据可靠存储。

1. 核心角色

  • Client:发起写请求,切分文件为 Block,管理数据传输·流水线。
  • NameNode:校验权限、分配 Block 存储位置(DataNode 列表),更新元数据。
  • DataNode:存储 Block,参与流水线传输,通过心跳汇报状态。

2. 详细流程(7 步)

  1. Client 发起写请求,NN 校验
    Client 通过 DistributedFileSystem 类向 NN 发送写文件请求(如 hdfs dfs -put localfile /hdfs/path),NN 校验以下内容:

    • Client 是否有目标路径的写入权限;
    • 目标路径是否已存在同名文件(未设置覆盖则返回错误);
    • 集群剩余空间是否满足文件大小(按“文件大小×副本数”计算)。
      校验通过后,NN 返回“允许写入”。
  2. Client 切分文件为 Block
    Client 按 HDFS 默认块大小(128MB,可配置)将文件切分为 Block,例如 1GB 文件切分为 8 个 128MB Block(最后一块可能不足 128MB),并为每个 Block 分配唯一标识(如 blk_1073741825)。

  3. Client 向 NN 申请 Block 存储位置
    Client 逐个向 NN 请求“当前 Block 的存储位置”,NN 按副本放置策略分配 DataNode 列表(以 3 副本为例):

    • 第 1 副本:优先 Client 所在节点(若 Client 在集群内),否则同机架随机节点;
    • 第 2 副本:与第 1 副本不同机架的随机节点(跨机架容错);
    • 第 3 副本:与第 2 副本同机架的随机节点(平衡容错与网络开销)。
      NN 返回分配的 DataNode 列表(如 [DN1, DN2, DN3])。
  4. 建立数据传输流水线(Pipeline)
    Client 与 DN1 建立 TCP 连接,DN1 再与 DN2 建立连接,DN2 与 DN3 建立连接,形成“Client→DN1→DN2→DN3”的流水线。连接建立后,DN3 向 Client 返回“准备就绪”确认。

  5. Client 向流水线传输数据
    Client 将 Block 拆分为更小的数据包(Packet,默认 64KB),放入本地缓冲区,通过流水线依次发送给 DN1:

    • DN1 接收后,一边写入本地磁盘,一边转发给 DN2;
    • DN2 同理,一边写入本地,一边转发给 DN3;
    • DN3 仅写入本地,不转发。
      每个 Packet 传输完成后,下游节点会返回 ACK 确认,确保数据无误。
  6. Block 写入完成,NN 更新元数据
    当 Block 的所有 Packet 传输完成且 3 个副本均写入成功后:

    • Client 向 NN 发送“Block 写入完成”通知;
    • NN 更新元数据(记录 Block 标识、所属文件、存储的 DN 列表等)。
  7. 重复流程至所有 Block 写入
    Client 按顺序处理下一个 Block,重复步骤 3-6,直至所有 Block 写入完成。最后 Client 向 NN 发送“文件写入完成”请求,NN 更新文件元数据(如文件大小、块数量),并返回“写入成功”。

3. 关键保障机制

  • 副本容错:若传输中某 DN 故障(如 DN2 宕机),Client 中断流水线,通知 NN 重新分配 DN4,从故障点重新传输未完成的 Packet,确保最终副本数达标。
  • 数据校验:每个 Block 生成对应的校验和(Checksum),存储在 .blk_xxx.crc 文件中,读取时验证数据完整性,避免损坏数据被使用。

四、HDFS 读数据流程

读数据流程的核心是“元数据获取→最优 DN 选择→数据读取→块拼接”,通过“数据本地化”机制减少网络开销,提升读取效率。

1. 核心角色

  • Client:发起读请求,选择最优 DN,拼接 Block 为完整文件。
  • NameNode:校验权限,提供 Block 与 DN 的映射关系。
  • DataNode:响应读请求,传输 Block 数据。

2. 详细流程(6 步)

  1. Client 发起读请求,NN 返回元数据
    Client 通过 DistributedFileSystem 向 NN 发送读文件请求(如 hdfs dfs -get /hdfs/path localpath),NN 校验:

    • Client 是否有文件读取权限;
    • 目标文件是否存在。
      校验通过后,NN 返回文件元数据:
    • 所有 Block 列表(如 Block1, Block2, ..., BlockN);
    • 每个 Block 的所有副本所在 DN 列表(如 Block1: [DN1, DN2, DN3])。
  2. Client 选择最优 DN
    Client 按数据本地化原则选择每个 Block 的读取节点,优先级如下:

    • 优先 Client 所在节点的 DN(本地读取,无网络传输);
    • 其次同机架的 DN(减少跨机架网络开销);
    • 最后其他机架的 DN(仅当同机架无副本时)。
      例:Client 在 NodeA,Block1 副本在 NodeA(DN1)、NodeB(DN2),则优先读 DN1。
  3. Client 与 DN 建立连接并读取 Block
    Client 与选定的 DN 建立 TCP 连接,发送“读取指定 Block”的请求。DN 从本地磁盘读取 Block 数据,传输给 Client。
    Client 接收数据时同步验证 Checksum:

    • 校验通过:确认数据完整;
    • 校验失败:放弃该 DN,选择同一 Block 的其他副本(如 DN2)重新读取。
  4. Client 拼接 Block 为完整文件
    Client 按 Block 顺序(Block1→Block2→...→BlockN)读取所有 Block,暂存到本地缓冲区,最终拼接为完整文件,写入本地磁盘(如 localpath)。

  5. 容错处理:读取失败切换副本
    若读取中 DN 故障(如网络中断),Client 立即中断连接:

    • 从该 Block 的其他副本 DN 重新读取;
    • 记录故障 DN,后续读取其他 Block 时避开(直至其恢复)。
  6. 读取完成,关闭连接
    所有 Block 读取并拼接完成后,Client 关闭与所有 DN 的连接,返回“读取成功”。

3. 关键优化机制

  • 数据本地化:减少跨节点/跨机架网络传输,符合 Hadoop“移动计算而非数据”的设计理念,是 HDFS 读效率高的核心原因。
  • 并行读取:Client 可同时向多个 DN 发起请求,并行读取不同 Block(如 Block1 读 DN1,Block2 读 DN4),缩短大文件总读取时间。

五、HDFS 元数据管理:fsimage、edits、seen_txid

NN 管理的元数据(目录结构、Block 映射等)是 HDFS 的核心,通过 fsimageeditsseen_txid 三个文件确保元数据的一致性和持久性。

1. 三个核心文件的作用与特点

文件 作用 特点
fsimage(文件系统镜像) 存储某一时刻 HDFS 的完整元数据快照,包括目录/文件 inode 信息(权限、所有者、修改时间)、文件与 Block 映射、Block 副本位置等。 静态文件,不实时更新;体积大,加载速度快,NN 启动时优先加载以恢复基础元数据。
edits(编辑日志) 记录 fsimage 快照之后的所有元数据变更操作(如创建文件、删除目录、修改权限、新增 Block 等)。 动态追加日志,每次变更立即写入,确保操作不丢失;需与 fsimage 配合使用以恢复最新元数据。
seen_txid(事务 ID 记录) 记录 NN 最后一次处理的 edits 日志的事务 ID(txid),标识元数据变更进度。 简单文本文件,内容仅为一个数字(如 1000);用于故障恢复时定位需重放的 edits 范围(从 seen_txid+1 开始)。

2. 三者协同关系

  • 正常运行:fsimage 保存历史快照,edits 实时记录新操作,seen_txid 跟踪最新 txid。
  • Checkpoint(检查点)机制:Secondary NameNode 定期(默认 1 小时或 edits 达到 100 万次操作)合并 fsimage 和 edits:
    1. 2NN 向 NN 请求“停止写入 edits,生成新的 edits.inprogress”;
    2. 2NN 下载 NN 的 fsimage 和 edits;
    3. 2NN 合并两者,生成新的 fsimage(fsimage.ckpt);
    4. 2NN 将新 fsimage 上传给 NN,NN 替换旧 fsimage,清空旧 edits,将 edits.inprogress 重命名为 edits;
    5. seen_txid 更新为最新 txid,完成合并。
      该机制避免 edits 文件过大导致 NN 启动时重放时间过长。

六、DataNode 可靠存储与故障处理(心跳汇报和块汇报)

DataNode 是 HDFS 的“存储载体”,其工作机制围绕“数据可靠存储”和“故障自动处理”展开。

1. 数据块存储

DataNode 存储 Block 时,会同时保存以下信息:

  • 数据本身:Block 的二进制数据,存储在磁盘指定目录。
  • 数据长度:记录 Block 的实际大小(避免读取不完整)。
  • 校验和:与 Block 对应的 Checksum,存储在 .blk_xxx.crc 文件中。
  • 时间戳:记录 Block 的创建/修改时间,用于版本管理。

2. 与 NameNode 的通信

  • 心跳汇报(Heartbeat):DN 每 3 秒向 NN 发送一次心跳,包含自身状态(存活状态、磁盘使用率、Block 数量等)。若 NN 超过 10 分钟(默认)未收到心跳,判定 DN 宕机,触发副本修复。
  • 块汇报(Block Report):DN 启动时或每隔 6 小时,向 NN 完整汇报自身存储的所有 Block 列表。NN 通过块汇报更新元数据(确保 Block 位置信息准确)。

3. 容错与数据可靠性保障

  • 数据块损坏检测:Client 读取 Block 时验证 Checksum(校验和),若不匹配(数据损坏),立即向 NN 报告。NN 标记该 Block 为“损坏”,指令其他 DN 复制健康副本到新节点,同时删除损坏 Block。
  • 节点故障处理:DN 宕机后,NN 检测到心跳超时,立即检查该 DN 上的所有 Block:
    • 对副本数不足的 Block(如原 3 副本,宕机后剩 2 个),NN 调度其他 DN 复制副本,直至满足 dfs.replication 配置(默认 3 副本)。
  • 磁盘故障处理:DN 定期检查本地磁盘状态,若某磁盘故障,标记该磁盘上的所有 Block 为“丢失”,通过块汇报告知 NN,由 NN 触发副本修复。

七、常见面试题:为什么 HDFS 数据块大小不能太小或太大?

HDFS 默认 Block 大小为 128MB(Hadoop 2.x+),其大小设置需平衡“元数据开销”“IO 效率”和“并行度”,过小或过大都会导致问题。

1. 数据块太小的问题

  • 元数据管理开销过大:NN 需存储每个 Block 的元数据,若 Block 太小(如 1KB),1GB 文件会拆分为 100 万个 Block,NN 内存需维护 100 万个元数据。PB 级集群下,元数据量会耗尽 NN 内存,甚至导致 NN 崩溃。
  • 计算任务调度效率低:MapReduce 等框架按 Block 划分 Map 任务(1 个 Block 对应 1 个 Map 任务)。Block 太小会产生大量 Map 任务,每个任务的启动、初始化、资源分配(如 JVM 创建)有额外开销,YARN 调度成本剧增,整体计算效率下降。
  • 磁盘寻道时间占比过高:磁盘读写包含“寻道时间”(磁头移动到数据位置,约毫秒级)和“传输时间”(数据读取到内存)。Block 太小会导致寻道时间占比远高于传输时间(如读 1KB 和 128MB Block 的寻道时间相同,但传输时间差异极大),磁盘 IO 效率低下。

2. 数据块太大的问题

  • 数据传输耗时过长:若 Block 太大(如 1GB),单次传输需更长时间。若传输中发生网络波动或 DN 故障,重试需重新传输整个 Block,重试成本极高,影响数据可靠性和任务进度。
  • 计算并行度不足:分布式计算的核心是“并行处理”,Block 太大导致 Map 任务数量过少。
posted @ 2025-10-14 16:45  Filament  阅读(11)  评论(0)    收藏  举报
返回顶端