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

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

总结口诀速记

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

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

http://www.lryc.cn/news/2398483.html

相关文章:

  • 建筑工程施工进度智能编排系统 (SCS-BIM)
  • Laravel模型状态:深入理解Eloquent的隐秘力量
  • Spring Cloud Eureka:微服务架构中的服务注册与发现核心组件
  • matlab实现求解兰伯特问题
  • iOS 集成网易云信的音视频呼叫组件
  • 【Elasticsearch】search_after不支持随机到哪一页,只能用于上一页或下一页的场景
  • 深度解析 Qt 最顶层类 QObject:继承关系与内存生命周期管理
  • pikachu通关教程-XSS
  • k8s fsGroup
  • Spring Boot,注解,@ConfigurationProperties
  • AIGC学习笔记(9)——AI大模型开发工程师
  • git管理github上的repository
  • STM32学习之WWDG(原理+实操)
  • Keil MDK5.37或更高版本不再预装ARM Compiler Version5导致编译错误的解决方法
  • 【iOS(swift)笔记-14】App版本不升级时本地数据库sqlite更新逻辑二
  • 前端性能优化:提升用户体验的关键策略
  • Unity-UI组件详解
  • 基于大模型的短暂性脑缺血发作(TIA)全流程预测与干预系统技术方案
  • 嵌入式学习 D31:系统编程--Framebuf帧缓冲
  • 黑马点评完整代码(RabbitMQ优化)+简历编写+面试重点 ⭐
  • Java 大视界 -- Java 大数据在智能安防视频监控中的异常事件快速响应与处理机制(273)
  • 【数据库】安全性
  • 【图像处理入门】4. 图像增强技术——对比度与亮度的魔法调节
  • D2-基于本地Ollama模型的多轮问答系统
  • HALCON 深度学习训练 3D 图像的几种方式优缺点
  • 123网盘SDK-npm包已发布
  • 强制卸载openssl-libs导致系统异常的修复方法
  • 乐播视频v4.0.0纯净版体验:高清流畅的视听盛宴
  • Linux 命令全讲解:从基础操作到高级运维的实战指南
  • FreeRTOS的简单介绍