Hadoop将底层文件系统抽象成FileSystem类,上层用户可以通过相同方法操作底层不同的文件系统。常用的方法有get一个FileSystem实例,open打开一个文件的输入流,然后通过输入流的read方法读取数据。下面简单地将这三个方法时序流程中主要环节以时序图形式表示(以文件系统为HDFS为例),以便读者有所了解。
- get方法获得FileSystem实例
FileSystem抽象类通过读取配置文件"core-site.xml"中属性"fs.default.name"的值,判断使用哪个文件系统,然后通过反射生成文件系统实例,后调用DistributedFileSystem(FileSystem的继承实现类)的initialize方法获取NameNode的代理客户端类。
- open方法打开输入流
通过get获得的NameNode代理客户端类使用RPC技术从NameNode得到文件所有块的位置。
NameNode返回块的位置数据格式如下所示:其中有文件大小,块是否损坏,每一个块所在的所有DataNode的位置,以及最后一个块的信息。
其中192.168.124.129为NameNode主机IP,192.168.124.130和192.168.124.131为DataNode主机IP.LocatedBlocks{
fileLength=3
underConstruction=false
blocks=[LocatedBlock{BP-891302631-192.168.124.129- 1504501047605:blk_1073741827_1003; getBlockSize()=3; corrupt=false; offset=0; locs=[DatanodeInfoWithStorage[192.168.124.130:50010,DS-32818ad7-b98d-4b43-a43d-669972cb5df7,DISK], DatanodeInfoWithStorage[192.168.124.131:50010,DS-338b6d03-c41b-4129-bffe-aa61c61ef975,DISK]]}]
lastLocatedBlock=LocatedBlock{BP-891302631-192.168.124.129-1504501047605:blk_1073741827_1003; getBlockSize()=3; corrupt=false; offset=0; locs=[DatanodeInfoWithStorage[192.168.124.130:50010,DS-32818ad7-b98d-4b43-a43d-669972cb5df7,DISK], DatanodeInfoWithStorage[192.168.124.131:50010,DS-338b6d03-c41b-4129-bffe-aa61c61ef975,DISK]]}
isLastBlockComplete=true}
- read方法读取数据
open得到的输入流对象是HdfsDatainputStream,HdfsDataInputStream输入流继承自FSDataInputStream,所以实际调用的是父类的read方法,FSDataInputStream中封装了DFSInputStream,所以又调用DFSInputStream的read方法,DFSInputStream中封闭了DFSClient(这是一个代理客户端类)。通过DFSClient使用open得到的块信息与DataNode沟通,得到块的数据。