现在的位置: 首页 > 综合 > 正文

Hadoop-0.20.0源代码分析(14)

2013年02月27日 ⁄ 综合 ⁄ 共 16325字 ⁄ 字号 评论关闭

Hadoop集群中,不同进程之间通信需要使用合适的协议才能够进行交互,之前对Hadoop给出的协议接口做了分析。在协议接口中约定了通信双方的特定行为,那么,在实现这些通信协议的实现类中,就能看到指定进程是如何实现协议接口中约定的行为的。这里,阅读分析org.apache.hadoop.hdfs.server.namenode.Namenode实现类。

首先,看一下Namenode类实现的接口,下面是该类声明:

可以看到,Namenode主要实现了ClientProtocol,DatanodeProtocol,NamenodeProtocol这三个用来通信的协议。其中,RefreshAuthorizationPolicyProtocol接口是定义所使用的认证策略,并能根据不同的应用场景来自动刷新其级别,以适应实际应用的需要。

Namenode是HDFS集群中的中心服务器,对于服务器的配置选项,可以通过加载配置文件来进行配置,所以该类中有如下加载配置资源的两行代码:

Namenode类中定义属性如下:

对上面几个重要的属性简单说明一下。

FSNamesystem也是org.apache.hadoop.hdfs.server.namenode包中的类,在Namenode类中是核心的、最重要的。该类主要的功能是对Datanode结点的一些状态等进行登记,便于Namenode进程能够快速获取到指定的Datanode结点的状态等的详细信息,以便进行任务的调度与分配。它主要跟踪如下几个重要的数据表:

1)文件系统到块的映射表(有效文件系统名字-->块列表);

2)全部有效块的列表;

3)块到主机的映射表(块-->主机列表);

4)主机到块的映射表(主机-->块列表);

5)LRU缓存(已经更新心跳状态的主机都放到LRU Cache中)。

HttpServer在org.apache.hadoop.http包中,提供了将Jetty服务器内置于Namenode服务器中,以便可以通过HTTP请求的方式来获取当前Namenode提供服务的信息。

Namenode提供了一个执行初始化的方法,如下所示:

在Namenode类实现中,其中实现的操作基本上都是由FSNamesystem来完成的。在这里,我们先不关心Namenode具体是如何实现那些基本操作的,而只是关注Namenode的功能特性,在后面再对FSNamesystem类进行分析。这里使用方式就是,根据Namenode所实现的接口中定义的操作,来分析Namenode服务器所具备的基本功能,或者说提供的基本服务。

NamenodeProtocol实现

在Namenode类中,实现了NamenodeProtocol协议接口中定义的getBlocks方法,如下所示:

给定DatanodeInfo datanode,它是一个描述Datanode的状态的实体类对象,通过getBlocks方法,可以获取到总的块大小为size的BlocksWithLocations,即描述这些块的位置信息的BlocksWithLocations对象。

ClientProtocol实现

实现ClientProtocol协议接口中定义的方法,如下所示:

 

DatanodeProtocol实现

Namenode需要与Datanode进行通信,所以必须实现与DatanodeProtocol协议接口。

下面是对DatanodeProtocol协议接口中定义的基本操作的实现:

其它实现

用于Namenode与客户端通信,还定义了如下几个与Namenode管理文件系统命名空间相关的操作,主要是对EditLog和FsImage文件的操作:

在Namenode上,对文件系统名字空间进行的任何操作,Hadoop采用记录事务日志的方式来保存这些操作的记录,对应的事务日志文件就是EditLog文件,该文件存放在磁盘上。而FsImage映像文件,是Hadoop集群工作的过程中使用的,便于Namenode进程管理文件系统的命名空间。当Namenode启动的时候,会首先读取EditLog与FsImage文件,并将EditLog作用于FsImage,因为此时FsImage文件一定是最新的事务日志记录文件的映像,并将EditLog文件删除(因为它可能会在Hadoop集群工作过程中变成旧的文件,也就是不是最新的事务记录);在Namenode启动之后工作的过程中,仍然会有对文件系统命名空间执行操作的事务记录,这些记录都被保存到一个新的EditLog事务日志文件中,以便下次启动Namenode的时候,将最新的事务日志记录作用于FsImage上。

另外,Namenode类中实现了创建一个Namenode实例的方法createNameNode,该方法是static的,通过命令行参数一个Hadoop配置类实例来创建一个Namenode实例,方法实现如下所示:

关于配置启动选项,可以查看org.apache.hadoop.hdfs.server.common.HdfsConstants接口中定义了枚举类StartupOption,如下所示:

上面创建一个Namenode,在解析完命令行参数后,得到一个枚举类实例,然后根据它来设置Namenode启动选项,如下所示:

接着,在构造Namenode实例之前,根据设置的附加启动选项,做一个预处理(格式化或某次升级之后的确认动作),如果是格式化操作,具体操作为:

关于FsImage与EditLog在文件系统中的所在位置的选择,在org.apache.hadoop.hdfs.server.namenode.FSNamesystem类中可以看到详细的情况。

如果是确认升级完成命令行,则实现如下所示:

关于FsImage文件的操作,可以查看org.apache.hadoop.hdfs.server.namenode.FSImage类的具体实现。在后面会专门对FSImage类进行详细阅读分析的。

下面,对Namenode类的实现做一个总结:

从Namenode实现类来看,它主要是实现了Namenode服务器进程与Datanode进程、文件系统客户端进程,以及Secondary NameNode进程进行交互过程中一些重要的基本的操作,具体表现为,Namenode实现了ClientProtocol协议来与客户端交互,实现了DatanodeProtocol协议来与Datanode进行交互,实现了NamenodeProtocol协议来与Secondary NameNode进行交互。而且,该类还给出了一个static方法,通过命令行的方式用来构造一个Namenode实例,并启动Namenode服务器进程。

抱歉!评论已关闭.