HDFS 读写流程:客户端、NameNode、DataNode 之间怎么配合
HDFS 的读写流程,本质上是三个角色配合完成一件事:
- 客户端:我要读/写数据
- NameNode:告诉我”数据在哪”或”数据该存哪”
- DataNode:真正干活的——存数据或给数据
整个流程的核心逻辑是:NameNode 管”位置”,DataNode 管”数据”,客户端不经过 NameNode 直接跟 DataNode 传数据。
写入流程:数据怎么进 HDFS
写入的核心机制叫 流水线复制(Pipeline Replication)——客户端把数据发给第一个 DataNode,第一个转发给第二个,第二个转发给第三个,像流水线一样。
写入流程时序图
sequenceDiagram
participant Client
participant NN[NameNode]
participant DN1[DataNode 1]
participant DN2[DataNode 2]
participant DN3[DataNode 3]
Client->>NN: 创建文件请求(/user/data.txt)
NN->>Client: 确认创建,返回文件句柄
Client->>NN: 请求分配第一个数据块
NN->>Client: 分配块 ID(blk_123),返回 DataNode 列表(DN1→DN2→DN3)
Client->>DN1: 建立写入流水线(blk_123)
DN1->>DN2: 建立连接
DN2->>DN3: 建立连接
Client->>DN1: 流式写入数据(64KB 数据包)
DN1->>DN2: 转发数据
DN2->>DN3: 转发数据
DN3->>DN2: 确认接收
DN2->>DN1: 确认接收
DN1->>Client: 确认接收
loop 直至所有数据写入
Client->>DN1: 发送下一个数据包
DN1->>DN2: 转发
DN2->>DN3: 转发
DN3->>DN2: 确认
DN2->>DN1: 确认
DN1->>Client: 确认
end
Client->>NN: 关闭文件请求
NN->>Client: 确认关闭,持久化元数据
分步拆解:
第一步:客户端问 NameNode——“我要写文件”
客户端发送创建文件请求,NameNode 检查权限和路径合法性,在元数据中创建文件节点。此时不分配块,只是占个位置。
第二步:客户端申请块——NameNode 分配位置
客户端开始写数据时,向 NameNode 申请一个新的数据块。NameNode 按机架感知策略选出一组 DataNode(默认 3 个),返回给客户端。
第三步:建立流水线——客户端连 DN1,DN1 连 DN2,DN2 连 DN3
客户端收到 DataNode 列表后,依次建立连接形成一条链。这保证了数据按固定顺序流动。
第四步:数据流式写入——客户端 → DN1 → DN2 → DN3
数据以 64KB 数据包的形式从客户端流向 DN1,DN1 边收边转给 DN2,DN2 边收边转给 DN3。每个数据包发完后,确认信息从 DN3 反向传回客户端。
第五步:关闭文件——NameNode 记下块的位置
客户端写完所有数据后,通知 NameNode 关闭文件。NameNode 把块的 ID 和位置信息持久化到 Edits。
关键设计点:
- 数据流和确认流分开:数据正向流,确认反向流,提高吞吐
- NameNode 不参与数据传输:只负责分配位置,避免成为瓶颈
- 管道中任何节点失败:客户端会关闭当前管道,用剩下的节点重建管道继续写