hdfs下载数据源码分析之open方法浅析

下面我们来看看open方法。

我们之前简单分析过,这个open方法,打开这个在hdfs上的文件的时候,首先是要通过和namenode的通信来确定这个文件的块在哪些datanode上面,然后通过建立与datanode的通信来获得对应块文件流。

Open方法返回的是文件系统的数据输入流,然后调用的是抽象的FSDataInputStream的方法,这个方法就是子类实现的方法了。下面是DistributedFileSystem的open方法。


分别代表的意思是读了多少字节,写了多少字节,有多少次读操作,有多少次大的读操作,有多少次写操作。

这行代码:Pathabsf=fixRelativePart(f),是把相对路径改为绝对路径,也就是将你传进来的关于hdfs上文件所在的路径进行针对的变化。

然后返回一个FileSystemLinkResolver,一个文件系统的连接的解析器对象,并调用解析方法去解析这个路径。

 

这个匿名内部类重写了两个方法,其中doCall方法是拿到流对象的关键。

这个匿名内部类的对象调用的resolver方法应该是回调了doCall方法,然后返回一个流对象,我们看这个doCall方法里面是用hdfsDataInputStream封装了dfs.open()获得的流对象,而这个dfs我们之前提到过是fs所持有的一个对象,它持有了一个可以和namenode进行通信的clientProtocal对象。

下面我们来看一下dfs.open()方法。

通过DFSInputStream的构造方法来构造一个对应文件的输入流。

然后我们来看看构造方法里面是什么:

DFSInputStream将dfsClient作为自己的一个成员。下面是DFSInputStream的一些成员。其中BlockReader就是去读各个block一个对象,里面应该是封装了一些对datanode进行数据获取的一些代码。然后locatedBlocks里面应该是存储了block的位置信息,通过dfsClient和namenode通信获得。这些成员的变量赋值都在openinfo()方法里面。


下面是openinfo()方法里面的内容。

为什么是要取块的位置信息并且取最后一个block块的长度?因为前面的块都是按照blocksize分的block,但是最后一块可能小于blocksize,这个时候就需要确定这个块的长度。

拿位置信息的时候还是通过dfsclient,可以看到是通过dfs中持有的可以和namenode通信的对象去进行block位置信息的获取的。

下面是callGetBlockLocations的源码。可以看到是通过namenode的getBlockLocations方法去和namenode进行通信,从而获得block信息。

以下是通过rpc客户端(namenode)代理对象调用服务端真实的实现去获得的信息。

 

其中,fileLength是文件的总长度,underConstruction代表文件是正常状态,然后blocks是此文件的block的位置,lastLocatedBlock是最后一块的位置,isLasBlockComplete-ture是最后一个block是否完全、完整的标志。

通过这些,我们已经拿到block信息,接下来就是dfsinputstream中blockreader赋值,赋完值之后就可以去datanode拿数据了。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值