您的位置:首页 > 大数据 > 物联网

Hadoop Herriot测试框架之旅—源码分析

2011-10-08 14:44 260 查看
在Hadoop-0.21.0的目录结构中,common、hdfs和mapred作为独立的工程存在,因此与Herriot有关的代码也分别在不同的工程中,其中common工程里的是通用的一些代码,hdfs工程中实现了对HDFS集群的测试,mapred工程中实现了对MapReduce集群的测试。在这三个工程中,Herriot的目录结构基本类似:src/test/system/[aop|java|test],其中,aop和java目录是和Herriot框架本身有关的,test目录是用于存放Herriot的测试用例的。下面,以Herriot在common和hdfs工程为例,我们来分析一下Herriot相关的代码。
common工程中src/test/system/java中有两个包:org.apache.hadoop.test.system和org.apache.hadoop.test.system.process,这两个包中的java代码是整个Herriot框架的基础,其中有下面几个类/接口:
l DaemonProtocol接口:该接口继承了VersionedProtocol接口,其实是声明了Herriot客户端和Herriot注入代码之间的RPC通信协议。在这接口中,声明了多种方法,支持客户端操作被注入的Hadoop节点,以及获得该节点的信息。
l ProcessInfo接口:该接口继承自Writable接口,声明了被注入Hadoop节点所属的远程JVM进程信息,比如环境变量,内存大小和当前时间等。该接口被DaemonProtocol中的某些方法作为返回结果使用,实则是封装了与远程JVM进程相关的信息。
l ProcessInfoImpl类:该类是ProcessInfo接口的一个具体实现。
l ControlAction类:该类是一个抽象类,实现了Writable接口,它实则是对Herriot客户端对被注入Hadoop节点的所作操作的封装。该类是DaemonProtocol中几个方法的参数或返回值。
l RemoteProcess接口:该接口声明了对单个远程进程的操作,包括获得主机名,启停操作以及获得该进程的角色。在Hadoop中,进程的角色被划分为:NN,DN,JT和TT,不过这些并不在common工程中定义的,而是分别在hdfs和mapred工程中定义的。
l ClusterProcessManager接口:该接口声明了对整个集群中进程的管理操作,比如获得所有RemoteProcess表述的远程进程以及它们的角色,启停集群中的所有进程,更新配置信息,是否支持多用户操作等。
l HadoopDaemonRemoteCluster类:该类是一个抽象类,它实现了ClusterProcessManager接口。此外,还完成了以几个事情:1. 定义了与测试依赖的环境变量,例如HADOOP HOME和HADOOP CONF DIR等键值;2. 定义了Set<Enum<?>>类型的成员变量roles来维护集群中成员的角色;3. 给出了RemoteProcess的一个具体实现内部类ScriptDaemon,它通过SSH方式远程登录到目标机器上实现RemoteProcess声明的操作;同时HadoopDaemonRemoteCluster类还维护了一个RemoteProcess类型的列表,表示集群中所有的远程进程;4.
定义了HadoopDaemonInfo内部类,代表一种类型的Hadoop节点的信息,包括:名字(如namenode, datanode等),角色和主机名列表;同时,HadoopDaemonRemoteCluster类还维护了一个List<HadoopDaemonInfo>类型的成员变量。
l MultiUserHadoopDaemonRemoteCluster类,该类是一个抽象类,他继承自HadoopDaemonRemoteCluster,它的内部类MultiUserScriptDaemon继承自ScriptDaemon,支持多用户对同一集群的操作。
l AbstractDaemonClient类:该类是一个抽象类,它通过代理模式封装了DaemonProtocol的子类接口(采用泛型<PROXY extendsDaemonProtocol>)和RemoteProcess接口(作为AbstractDaemonClient的一个成员变量),对它的调用基本会转化为对DaemonProtocol/RemoteProcess的调用。一个AbstractDaemonClient子类的对象对应于管理一个Hadoop节点的客户端。
l AbstractDaemonCluster类:该类是一个抽象类,它是Herriot框架下集群的抽象。它拥有两个重要的成员变量:1. ClusterProcessManager类型的clusterManager,维护了该集群中所有远程进程的管理操作;2.Map<Enum<?>,List<AbstractDaemonClient>>类型的daemons变量,维护了不同角色下所有客户端的列表。

common工程中src/test/system/aop中只有一个文件:DaemonProtocolAspect.aj。该文件就是DaemonProtocol接口的一个具体实现,不过该实现是以AOP方式注入到Hadoop节点的字节码中,所以不是java文件,而是aj(aspectJ)文件。与AOP相关的目录还有src/test/aop,它主要实现了生成注入后的字节码,与Herriot框架本身没有太大关系,所以不做过多讨论。
有了前面的分析,hdfs工程中的Herriot代码就不难理解了。hdfs工程的Herriot相关java代码仍放在src/test/system/java中,里面只有一个包org.apache.hadoop.hdfs.test.system,所有文件如下:
l NNProtocol接口,继承自DaemonProtocol,里面并没有新增方法。
l DNProtocol接口,继承自DameonProtocol,里面并没有新增方法。
l HDFSDaemonClient抽象类,它继承了AbstractDaemonClient,新增了获得namenode目录(dfs.name.dir)和datanode目录(dfs.data.dir)的方法.
l NNClient类,继承了HDFSDaemonClient<NNProtocol>,提供了connect和disconnect方法用于连接/断开Namenode的IPC端口。
l DNClient类,继承了HDFSDaemonClient<DNProtocol>,提供了connect和disconnect方法用于连接/断开Datanode的IPC端口。
l HDFSCluster类,继承了AbstractDaemonCluster抽象类,它真正实现了在Herriot框架下对HDFS集群的模拟。该类里面定义了HDFS节点的角色:NN和DN,并且根据不同的角色创建不同的Client类。另外,它还定义了两个类:HDFSProcessManager和MultiUserHDFSProcessManager,分别继承自HadoopDaemonRemoteCluster和MultiUserHadoopDaemonRemoteCluster。在启动HDFSCluster过程中,需要读到hdfs-site.xml和system-test.xml文件,在system-test.xml中根据配置test.system.hdfs.clusterprocess.impl.class指定的类来选择HDFSProcessManager或MultiUserHDFSProcessManager来创建cluster
process manager。
在src/test/system/aop目录下,由NNProtocol的具体实现NameNodeAspect.aj和DNProtocol的具体实现DataNodeAspect.aj,都是通过AOP方式来修改相应类的字节码。
根据上述分析,我们可以得出下面一个类的关系图:



[align=center] [/align]

[align=left] [/align]

总结一下,Herriot测试框架是通过“内部”和“外部”两种方式实现对分布式系统进行管理的,所谓“内部”就是通过AOP技术将测试所需的管理功能注入到节点中,管理的协议是通过DaemonProtocol接口以及它的扩展类来声明和定义的;而“外部”就是通过类似SSH方式远程登录到目标机器上,对远程进程进行操作,管理的协议是通过RemoteProcess接口以及它的扩展类来声明和定义的。一般而言,Herriot测试框架中抽象出来的集群HDFSCluster需要从配置文件中读取相应的信息,通过“外部”的方式启动真实HDFS集群中的节点,然后通过“内部”的方式获取更丰富的信息和操作,最后以“外部”的方式停止掉HDFS集群。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: