Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1944490
  • 博文数量: 1000
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 7921
  • 用 户 组: 普通用户
  • 注册时间: 2013-08-20 09:23
个人简介

storage R&D guy.

文章分类

全部博文(1000)

文章存档

2019年(5)

2017年(47)

2016年(38)

2015年(539)

2014年(193)

2013年(178)

分类: 服务器与存储

2015-02-10 11:04:14

读取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集合中;
  2.4)以List集合为参数初始化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步操作。
阅读(575) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~