标签:style blog http color io 使用 java ar strong
1. NameNode本质
经过前面的学习,可以知道NameNode 本身就是一个java 进程。观察RPC.getServer()方法的第一个参数,发现是this,说明NameNode 本身就是一个位于服务端的被调用对象,即NameNode 中的方法是可以被客户端代码调用的。根据RPC 运行原理可知,NameNode暴露给客户端的方法是位于接口中的。
我们查看NameNode 的源码,如图1.1所示。图 1.1
可以看到NameNode 实现了ClientProtocal、DatanodeProtocal、NamenodeProtocal 等接口。
2. NameNode的接口
2.1 DFSClient 调用ClientProtocal
<1> 这个接口是供客户端调用的。这里的客户端不是指的我们自己写的代码,而是hadoop 的一个类叫做DFSClient。在DFSClient 中会调用ClientProtocal 中的方法,完成一些操作。
<2>该接口中的方法大部分是对HDFS 的操作,如create、delete、mkdirs、rename 等。
2.2 DataNode 调用DatanodeProtocal
这个接口是供DataNode 调用的。DataNode 调用该接口中的方法向NameNode 报告本节点的状态和block 信息。NameNode 不能向DataNode 发送消息, 只能通过该接口中方法的返回值向DataNode 传递消息。
2.3 SecondaryNameNode 调用NamenodeProtocal
这个接口是供SecondaryNameNode 调用的。SecondaryNameNode 是专门做NameNode 中edits 文件向fsimage 合并数据的。
按照分析NameNode 的思路,看一下DataNode 的源码接口,如图2.1 所示。
这里有两个接口,分别是InterDatanodeProtocal、ClientDatanodeProtocal。这里就不展开分析了。读者可以根据上面的思路独立分析。
1. HDFS 的写数据过程分析
<1>我们通过FileSystem 类可以操控HDFS,那我们就从这里开始分析写数据到HDFS 的过程。在我们向HDFS 写文件的时候,调用的是FileSystem.create(Path path)方法,我们查看这个方法的源码,通过跟踪内部的重载方法,可以找到如图3.1所示的调用。
<2>这个方法是抽象类,没有实现。那么我们只能向他的子类寻找实现。FileSystem 有个子类是DistributedFileSystem,在我们的伪分布环境下使用的就是这个类。我们可以看到DistributedFileSystem 的这个方法的实现,如图3.2示。
图3.2
在图3.2中,注意第186 行的返回值FSDataOutputStream。这个返回值对象调用了自己的构造方法,构造方法的第一个参数是dfs.create()方法。
<3>我们关注一下这里的dfs 对象是谁,create 方法做了什么事情。现在进入这个方法的实现,如图3.3 所示。
在图3.3 中,返回值正是第866行创建的对象。
<3>这个类有什么神奇的地方吗?我们看一下他的源码,如图3.4 所示。
图3.4
在图3.4 中, 可以看到, 这个类是DFSClient 的内部类。在类内部通过调用namenode.create()方法创建了一个输出流。
<4>我们再看一下namenode 对象是什么类型,如图3.5所示。
图3.5
在图3.5 中,可以看到namenode 其实是ClientProtocal 接口。
<5>那么,这个对象是什么时候创建的那?如图3.6 所示。
可以看出,namenode 对象是在DFSClient 的构造函数调用时创建的,即当DFSClient 对象存在的时候,namenode 对象已经存在了。
<6>至此,我们可以看到,使用FileSystem 对象的api 操纵HDFS,其实是通过DFSClient 对象访问NameNode 中的方法操纵HDFS 的。这里的DFSClient 是RPC 机制的客户端,NameNode是RPC 机制的服务端的调用对象,整个调用过程如图3.7所示。
在整个过程中,DFSClient 是个很重要的类,从名称就可以看出,他表示HDFS 的Client,是整个HDFS 的RPC 机制的客户端部分。我们对HDFS 的操作,是通过FileSsytem 调用的DFSClient 里面的方法。FileSystem 是封装了对DFSClient 的操作,提供给用户使用的。
2. HDFS 的读数据过程分析
<1>我们继续对FileSystem 类分析,读数据使用的是open(…)方法,我们可以看到源码,如图3.8 所示。
图3.8
在图3.8 中,返回的是DFSClient 类中DFSDataInputStream 类.显而易见,这是一个内部类。
<2>这个内部类的构造函数,有两个形参,第一个参数是dfs.open(…)创建的对象。我们看一下方法的源码,如图3.9所示。
在图3.9的实现中,返回的是一个DFSInputStream 对象。
<3>该对象中含有NameNode 中的数据块信息。我们看一下这个类的构造方法源码,如图3.10 所示。
图3.10
<4>在图3.10中,这个构造方法中最重要的语句是第1836 行,打开信息,从第1842 行开始是openInfo()的源代码,截图显示不全。注意第1841 行,是获取数据块的信息的。我们查看这一行的源代码,如图3.11所示。
图3.11
从图3.11 中可以看到,获取数据块信息的方法也是通过调用namenode 取得的。这里的namenode 属性还是位于DFSClient 中的。通过前面的分析,我们已经知道,在DFSClient类中的namenode 属性是ClientProtocal。
标签:style blog http color io 使用 java ar strong
原文地址:http://www.cnblogs.com/sunddenly/p/3983490.html