HDFS读文件流程
网络读
最基本的一种HDFS读操作,DFSClient和Datanode通过建立Socket连接传输数据
详细流程
- 客户端通过DistributedFileSystem对象获取到一个DFSClient,之后通过open()方法打开HDFS文件,该对象会返回一个FSDataInputStream对象,实际上是DFSInputStream的一个装饰类
- 在DFSInputStream的构造方法中会调用getBlockLocations()方法向namenode获取该文件起始几个数据块的位置信息,Namenode返回的数据块的副本位置根据网络拓扑按照与客户端的距离远近排序。DFSInputStream会选择最优的Datanode建立socket连接读取数据
- 客户端通过调用DFSInputStream的read()方法,向Datanode读取数据块,数据块会以数据包(packet)为单位从数据节点通过流式接口传送到客户端。当达到这一批数据块的末尾时,DFSInputStream会关闭与该Datanode的连接,然后再次调用getBlockLocations获取下一批数据块的位置信息,然后继续读取;这个过程对于客户端是透明的。
读数据的过程中遇到错误怎么办?
- DFSInputStream与Datanode通信时遇到错误,DFSInputStream会从另一个最邻近的存储该数据块副本的Datanode继续读取,并且会记住这个故障的Datanode,确保之后不会再读取该节点上存储的后续的块
- DFSInputStream会检验Datanode发来的数据是否正确,如果发现有损坏的块,DFSInputStream会从其它的Datanode读取,并将损坏的数据块通知给Namenode
短路读
当DFSClient和保存目标数据块的Datanode在同一台物理节点上时,DFSClient可以直接打开数据块副本文件读取数据,而不需要Datanode进程的转发
零拷贝读
当DFSClient和缓存目标数据块的Datanode在同一台物理节点上时,DFSClient可以通过零拷贝的方式读取该数据块,大大提高了效率。即使在读数据的过程中,该数据块被Datanode从缓存中移除了,读取操作也可以转化为短路读。