HDFS读写流程

一 HDFS 客户端读文件流程


1打开HDFS文件: HDFS客户端首先调用DistributedFileSystem

.open方法打开HDFS文件,底层会调用ClientProtocal.open方法,返回一个用于读取的HdfsDataInputStream对象

2从NameNode获取DataNode地址:在构造DFSInputStream的时候,对调用ClientPortocal.getBlockLocations方法向NameNode获取该文件起始位置数据块信息。NameNode返回的数据块的存储位置是按照与客户端距离远近排序的。所以DFSInputStream可以选择一个最优的DataNode节点,然后与这个节点建立数据连接读取数据块

3连接到DataNode读取数据块: HDFS客户端通过调用DFSInputSttream从最优的DataNode读取数据块,数据会以数据包packet形式从DataNode以流式接口传送到客户端,当达到一个数据块末尾的时候,DFSInputStream就会再次调用ClientProtocal.getBlockL

Octions获取下一个数据块的位置信息,并建立和这个新的数据块的最优节点之间的连接,然后HDFS继续读取数据块

4客户端关闭输入流

注意:客户端读取数据块的时候,很有可能这个数据块的DataNode出现异常,也就是无法读取数据。这时候DFSInputStream会切换到另一个保存了这个数据块副本的DataNode,然后读取数据。另外,数据块的应答不仅包含了数据块还包含了校验值,HDFS客户端收到数据应答包的时候,会对数据进行校验,如果校验错误,也就是DataNode这个数据块副本出现了损坏,HDFS 客户端会通过ClientProtocal.reportBadBlocks向NameNode汇报这个损坏的数据块副本,同时DFSInputStream会尝试从其他DataNode读取这个数据块

二 HDFS 客户端写文件的流程


简单的流程介绍:

1HDFS 客户端调用DistributedFileSystem.create()方法

2底层在调用ClientProtocal,create()方法在NameNode的文件系统目录树中创建一个文件,并且创建新文件的操作记录到editlog中,返回一个HdfsDataOutputStream对象,底层是对DFSOutputStream进行了一个包装。

3HDFS 客户端根据返回的输出流对象调用write方法来写数据

4由于之间创建的新文件是一个空文件,并没有申请任何数据块,所以DFSOutputStream首先会调用ClientProtocal.addBlock向NameNode

申请数据块,数据块的大小可以由用户自己配置,默认128M,NameNode返回一个LocatedBlock对象,这个对象保存了这个数据块所有DataNode位置信息,然后就可以建立数据流管道写数据块了

5建立通向DataNode的数据流管道,写入数据:建立数据流管道之后,HDFS客户端就可以向数据流管道写数据。它会将数据切分成一个个的数据包packet,然后通过数据流管道发送到DataNode

6每一个packet都有一个确认包,逆序的通过数据流管道回到输出流。输出流在确认了所有的DataNode已经写入了这个数据包,就会从对应的缓存队列删除这个数据包

7当DataNode成功接收一个数据块时,DataNode会通过DataNodeProtocal.blockReceivedAndDelete方法向NameNode汇报,NameNode会更新内存中数据块和数据节点的对应关系

8完成操作后,客户端关闭输出流

 

三 DataNode写文件的流程

HDFS客户端通过流式接口DataTransferProtocol的子类Sender调用writeBlock,向数据流管道写入数据。在写的时候会传入从NameNode查询到的可用DataNode的信息。

 

DataNode在启动的时候,会创建DataXceiverServer对象,并以后台方式运行,DataXceiverServer是一个线程类,它会一直判断DataNode是否运行正常,监听是否有请求进来;如果有新的请求进来,则构造一个流式接口DataTransferProtocol的子类Receiver子类:DataXceiver线程服务这个请求,并启动这个DataXceiver。

 

DataXceiver启动之后,会解析当前输入流中的操作,是读还是写等,我们这里是写操作,那么操作码就是:WRITE_BLOCK,然后根据解析的WRITE_BLOCK作为参数,针对不同的操作码调用Receiver不同的方法,比如这里就是opWriteBlock方法.

 

客户端会将数据块切分成不同的数据包packet,数据包首先发送到第一个DataNode节点,成功接收后,会将数据包写入磁盘,然后将数据包发送到数据流管道中的第二个DataNode节点,以此类推,到数据流管道最后一个也就是第三个DataNode,会对收到的数据包进行校验,校验成功,DataNode3会发送数据包确认消息,这个消息会逆向的通过数据流管道回到客户端。当一个数据块中所有数据包发送完毕,并且受到确认消息,客户端会发送一个空的数据包标识当前数据块已经发送完毕。

 

 

 

四 DataNode读文件过程

HDFS客户端发送Sender.readBlock之后,DataXceiverServer检测到有新的请求到来,监听是否有请求进来;如果有新的请求进来,则构造一个流式接口DataTransferProtocol的子类Receiver子类:DataXceiver线程服务这个请求,并启动这个DataXceiver。

 

DataXceiver启动之后会解析请求操作,并根据请求操作码调用具体的方法opReadBlock。

 


  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

莫言静好、

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值