HDFS写数据流程

在客户端上传文件:hadoop hf -put xxx.txt时,流程如下图所示:

1.客户端向NameNode发送上传文件请求:hadoop hf -put xxx.avi  /aaa

2.NameNode对客户端进行响应,文件系统可以上传文件;

3.客户端通过rpc请求NameNode上传第一个block文件块,块的大小默认是128MB,主要是请求文件系统下将block写到哪个dataNode。

4.NameNode选择DataNode,选择策略是空间和距离,空间是dataNode磁盘大小,距离主要是网络的ip段,经过路由器的个数,具体做法:

    (1)第一个dataNode应与客户端在同一ip下(同一机架),或者最近的(根据网络段进行判断)

    (2)第二个dataNode考虑与客户端不在同一网段下(ip),主要是提高系统的可靠性;

   (3)第三个dataNode应与client端在同一ip下;

。。。。三个副本的情况。。。。。。

注:hadoop通过配置文件(机架感知配置文件)知道dataNode的距离;

5.client向第1个dataNode发送建立block传输通道channel,第1个dataNode将该请求发送到第2个dataNode,第二个dataNode将该请求发送第3个dataNode,直到第n-1个dataNode将该请求发送到第n个dataNode;

6.第n个接收请求的dataNode将相应成功信息传递到第n-1个dataNode,直到第1个dataNode,第1个dataNode将应答信息传递给客户端;

7.第一个block开始上传,以数据包packet为单位进行传送:

    (1)对每个block进行校验

    (2)将每个packet包放到第1个dataNode的缓存ByteBuff中,

    (3)第1个dataNode将ByteBuff中的数据写入到block中;

    (4)第1个dataNode的缓存ByteBuff中数据传送到第2个dataNode的bytebuff,然后第2个bytebuffer将数据写入block块中,第2个bytebuffer传送到第3个dataName以此类推。

备注

(1)只要一个block块上传成功,就算成功,之后nameNode会做异步的同步

(2)每上传一个block块,client都需要向nameNode发送请求



### HDFS 数据读过程详解 #### 1. 入数据到 HDFS 的详细流程 当客户端应用程序向 HDFS入文件时,具体操作如下: - 客户端调用 `create()` 方法创建文件并获得输出流对象。此时会联系 NameNode 来确认目标文件是否存在以及获取分配 Block ID 和 DataNodes 列表的信息[^2]。 - 获取到允许后,客户端开始分片上传数据至指定的第一个 DataNode 节点,在传输过程中还会通知其他参与存储副本的 DataNodes 形成管道结构。 - 当第一个 DataNode 接收到部分数据包之后立即将其转发给下一个节点直到最后一个节点完成接收为止;与此同时每个接收到的数据块都会被临时保存于内存缓冲区等待持久化处理。 - 所有的 DataNode 都成功入该片段后会给客户端返回 ACK 确认消息表示这一轮复制结束可以继续发送下一部分内容直至整个文件全部传完。 ```java // 创建文件并向其中入数据 FileSystem fs = FileSystem.get(conf); FSDataOutputStream out = fs.create(new Path("/user/test.txt")); out.writeBytes("This is test content."); out.close(); fs.close(); ``` #### 2. 从 HDFS 读取数据的过程 对于从 HDFS 文件系统中读取文件的操作而言,主要经历以下几个阶段: - 应用程序通过调用 `open()` 函数打开所需的目标文件得到输入流实例,并请求 NameNode 提供有关此文件元数据信息(比如 block 大小、block locations)以便规划最优读取策略。 - 根据所获知的位置列表按顺序连接各个拥有相应 fragment 的 DataNodes 进行实际的数据拉取工作。如果当前节点发生故障则尝试切换到备选位置重新建立链接关系来保障连续性。 - 在每次成功下载一段完整的 chunk 后即刻传递给应用层做进一步解析或展示而不必等到整份文档完全加载完毕再统一交付使用从而实现边读边用的效果提升效率。 ```java // 打开文件并从中读取数据 FileSystem fs = FileSystem.get(conf); Path filePath = new Path("/user/test.txt"); FSDataInputStream in = fs.open(filePath); byte[] buffer = new byte[1024]; int bytesRead = in.read(buffer); // 尝试读取最多1KB的数据 String data = new String(buffer, 0, bytesRead); System.out.println(data); in.close(); fs.close(); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值