当前位置: 首页 > news >正文

HDFS 写入和读取流程


HDFS 写入流程细化

1. 主线流程速记口诀

“先找主脑定文件,分配块副找节点;流水传块多副本,写完通知主脑存。”


2. 详细流程拆解

1. 客户端请求上传(Create 文件)

关键方法:

  • org.apache.hadoop.fs.FileSystem#create
  • org.apache.hadoop.hdfs.DistributedFileSystem#create
  • RPC 调用:ClientProtocol#create

内部逻辑:

  • 客户端调用 FileSystem#create(path),通过 RPC 向 NameNode 发起“我要新建文件”请求。

源码片段:

// FileSystem.java
FSDataOutputStream out = fs.create(new Path("/user/hadoop/test.txt"));
// DistributedFileSystem.java
public FSDataOutputStream create(Path f, ...) {return dfs.create(getPathName(f), ...);
}
// DFSClient.java
public OutputStream create(String src, ...) {namenode.create(src, ...); // RPC 请求
}

口诀注释:
主脑即 NameNode,先发“新建”请求。


2. NameNode 检查与元数据创建

关键方法:

  • org.apache.hadoop.hdfs.server.namenode.FSNamesystem#startFile
  • FSDirectory#addFile

内部逻辑:

  • NameNode 检查目录和权限,文件是否已存在。
  • 创建文件元数据,登记文件名、父目录、权限等。

源码片段:

// FSNamesystem.java
public void startFile(...) {// 检查目录、权限// 创建 INodeFile// 记录日志
}

口诀注释:
主脑查目录权限,登记新文件元数据。


3. Block 分配与 DataNode 列表下发

关键方法:

  • org.apache.hadoop.hdfs.server.namenode.FSNamesystem#allocateBlock
  • BlockManager#chooseTarget4NewBlock

内部逻辑:

  • NameNode 根据副本策略,选择 DataNode 并分配块。
  • 返回块 ID 和 DataNode 列表给客户端。

源码片段:

// FSNamesystem.java
LocatedBlock locatedBlock = allocateBlock(...);// BlockManager.java
chooseTarget4NewBlock(...)

口诀注释:
分配块副本,选定存放节点。


4. 客户端流水线写数据块

关键方法:

  • org.apache.hadoop.hdfs.DFSOutputStream#writeChunk
  • DataStreamer#run

内部逻辑:

  • 客户端建立与第一个 DataNode 的连接,DataNode 之间串联成流水线。
  • 数据块被切分成 packet,按顺序流向各 DataNode。
  • 每个 DataNode 写磁盘并返回 ACK。

源码片段:

// DFSOutputStream.java
writeChunk(...); // 写入数据
// DataStreamer.java
run(); // 负责数据传输和 ACK 处理

口诀注释:
流水线传块,副本级联写入。


5. 块写入完成与确认

关键方法:

  • DataNode#blockReceivedAndDeleted
  • NameNode#complete

内部逻辑:

  • 所有块写入完毕后,客户端通知 NameNode。
  • NameNode 更新文件状态为“已完成”,持久化元数据。

源码片段:

// DFSClient.java
namenode.complete(src, clientName, ...);
// FSNamesystem.java
completeFile(...); // 完成文件写入

口诀注释:
写完通知主脑,文件状态完成。


6. 写入流程图(Mermaid)

Client NameNode DataNode1 DataNode2 DataNode3 create() 分配Block和DataNode列表 写数据块 副本转发 副本转发 ACK complete() Client NameNode DataNode1 DataNode2 DataNode3

HDFS 读取流程细化

1. 主线流程速记口诀

“先问主脑要位置,选好节点取数据;分块并发快下载,组装文件得全局。”


2. 详细流程拆解

1. 客户端请求读取

关键方法:

  • org.apache.hadoop.fs.FileSystem#open
  • RPC:ClientProtocol#getBlockLocations

内部逻辑:

  • 客户端调用 open(path),通过 RPC 向 NameNode 请求块和 DataNode 的位置信息。

源码片段:

// FileSystem.java
FSDataInputStream in = fs.open(new Path("/user/hadoop/test.txt"));
// DFSClient.java
public LocatedBlocks getBlockLocations(String src, ...) {return namenode.getBlockLocations(src, ...); // RPC
}

口诀注释:
主脑给出块位置,客户端拿到 DataNode 列表。


2. NameNode 返回块元数据

关键方法:

  • org.apache.hadoop.hdfs.server.namenode.FSNamesystem#getBlockLocations

内部逻辑:

  • NameNode 查询文件块分布,返回每个块的 DataNode 列表。

源码片段:

// FSNamesystem.java
getBlockLocations(...);

口诀注释:
主脑查块分布,返回节点清单。


3. 客户端读取数据块

关键方法:

  • org.apache.hadoop.hdfs.DFSInputStream#read
  • BlockReaderFactory#newBlockReader

内部逻辑:

  • 客户端从 DataNode 读取数据块,可并发多线程读取不同块。
  • 自动选择健康的 DataNode,若失败自动切换。

源码片段:

// DFSInputStream.java
BlockReader reader = new BlockReaderFactory(...).build();
reader.read(...);

口诀注释:
并发取块,健康优先,故障切换。


4. 数据组装

关键方法:

  • FSDataInputStream#read
  • 由客户端按块顺序拼接还原文件

内部逻辑:

  • 客户端按文件逻辑顺序拼接所有块数据,得到完整文件。

源码片段:

// FSDataInputStream.java
int n = in.read(buffer);

口诀注释:
拼接数据块,文件得全局。


5. 读取流程图(Mermaid)

Client NameNode DataNode1 getBlockLocations() 返回块和DataNode列表 读取数据块 组装完整文件 Client NameNode DataNode1

总结口诀速记

  • 写入口诀
    “先找主脑定文件,分配块副找节点;流水传块多副本,写完通知主脑存。”
  • 读取口诀
    “先问主脑要位置,选好节点取数据;分块并发快下载,组装文件得全局。”

如需某个流程的源码更详细解析或更深入的注释,可以告诉我要哪个部分!

相关文章:

  • 40、响应处理-【源码分析】-基于请求参数的内容协商原理
  • Flink 失败重试策略 :restart-strategy.type
  • 学习threejs,交互式神经网络可视化
  • 三、kafka消费的全流程
  • 论文分类打榜赛Baseline:ms-swift微调InternLM实践
  • LangChain基本概念
  • Numpy入门2——视图和副本、伪随机数、切片和索引、数组的轴操作
  • Python训练打卡Day41
  • BugKu Web渗透之game1
  • 20250603在荣品的PRO-RK3566开发板的Android13下的使用命令行来查看RK3566的温度【显示优化版本】
  • 【 java 集合知识 第一篇 】
  • Python趣学篇:从零打造智能AI井字棋游戏(Python + Tkinter + Minimax算法)
  • 云原生周刊:探索 Gateway API v1.3.0
  • 深入理解Android进程间通信机制
  • 开疆智能Profinet转Profibus网关连接CMDF5-8ADe分布式IO配置案例
  • 【大模型:知识图谱】--1.py2neo连接图数据库neo4j
  • vue-14(使用 ‘router.push‘ 和 ‘router.replace‘ 进行编程导航)
  • Spark 单机模式部署与启动
  • 6-2 MySQL 数据结构选择的合理性
  • 【数据结构 -- B树】
  • 网站建设投票系统设计/外链工具在线
  • 新世纪建设集团有限公司网站/网址查询服务器地址
  • 北京seo薪资/广州网络推广seo
  • 乐都企业网站建设哪家快/网页设计学生作业模板
  • 免费ppt模板下载党建/北京网优化seo优化公司
  • 设计页面宽度/郑州seo代理外包