HDFS读取文件的整体流程概述

读取HDFS的整体流程图如下,下面根据此图对整个操作进行大致介绍

                    

1.调用DistributedFileSystem.open(Path path, int bufferSize)方法,主要完成初始化DFSInputStream对象的工作,并将DFSInputStream对象作为参数初始化DFSClient.DFSDataInputStream对象(DFSClient.DFSDataInputStream类继承FSDataInputStream类),并返回DFSClient.DFSDataInputStream对象给客户端;

2.在初始化DFSInputStream对象的时候,调用NameNode.getBlockLocations(String path,long offset, long length)向NameNode查询路径path的文件对应的所有block以及存放各个block块的DataNode信息,一个block块对应着多个DataNode,大致逻辑如下:
  2.1)通过路径path在FSNamesystem.dir.roorDir目录树状结构中查找对应的INode节点;
  2.2)从INode节点获取所有的Block对象,存入Block[]数组中;
  2.3)遍历Block[]数组,查找存放此Block对象的所有DataNode信息,即BlockInfo对象的三元数组object[]的object[index*3]值,将每个Block对象以及对应所有DataNode信息封装成LocatedBlock对象;最后全部添加到List<LocatedBlock>集合中;
  2.4)以List<LocatedBlock>集合为参数初始化LocatedBlocks对象,并赋值给DFSInputStream.locatedBlocks变量;
3.至此,客户端生成了DFSClient.DFSDataInputStream对象,并且此类引用了DFSInputStream类,即拥有了block块对应的DataNode信息(DFSInputStream.locatedBlocks变量)
客户端发起调用(DFSClient.DFSDataInputStream)FSDataInputStream.read(byte buf[], int off, int len)方法:
  3.1)根据读取偏移量找到下一个需要读取的Block块;
  3.2)然后找到存储此Block块的DataNode信息;
  3.3)若此DataNode为本地地址,则创建一个BlockReaderLocal对象;首先与DataNode交互,根据Block块从FSDataset.volumeMap中获取"blk_blockid"文件的File对象以及对应meta文件的File对象;然后分别创建两个FileInputStream对象,最后利用这两个FileInputStream对象完成文件的读取;文件读取操作结束。
  3.3)若此DataNode为远程地址,则创建一个RemoteBlockReader对象;
     3.3.1)根据DataNode信息建立Socket;
     3.3.2)根据Socket创建网络输出流DataOutputStream,并发送读取文件的请求信息给DataNode端;
     3.3.3)根据Socket创建网络输入流DataInputStream,用于读取DataNode返回的文件内容;
4.当DataNode为远程地址,就要执行此步获取DataNode上的文件内容;DataNode端是由DataXceiverServer线程专门负责监听请求,由DataXceiver线程负责处理请求;DataXceiver线程首先从网络输入流DataInputStream中解析客户端发送的读文件请求消息参数,然后根据blockid查找对应的block文件,并写入网络输出流中;若此DataNode读取失败,则会在从Block块对应的其他DataNode中重新读取文件,即第5步操作。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值