Hadoop-0.20.0源代码分析(06)

在阅读Hadoop源代码过程中,在org.apache.hadoop.security.UnixUserGroupInformation类中,需要获取到Unix系统的用户名和所属组的信息,就需要通过执行Shell命令得到相应的结果,这里,通过阅读Hadoop项目org.apache.hadoop.util包、org.apache.hadoop.fs.shell包、org.apache.hadoop.fs包中文件来了解,Hadoop基于Shell命令与底层Unix操作系统的交互,以及在MapReduce模型中通过命令行的方式提交管理计算任务的一些详细情况。

首先看一下,与Unix系统命令行执行有关的一些类的继承层次关系:

Shell命令最顶层的抽象类是org.apache.hadoop.util.Shell,它定义了如何在当前文件系统环境中,与底层的Unix系统通过命令行进行必要的交互。

从org.apache.hadoop.util.Shell类定义的属性来看,可以分为两种类型的属性,一种是static final的字符串命令,另一种是与实现命令的执行相关的属性。第一种属性(我把两个static final的获取命令的方式也列出,放到这里的属性的后面)如下所示:

看到这些Unix的命令,应该非常熟悉。

第二种属性,都属于与如何实现定义的上述命令行的执行有关的,如下所示:

dir属性表示当前执行命令所在的工作目录,environment属性表示当前命令执行的环境,它们在Shell类中都提供了一个受保护的设置操作,可以在Shell抽象类的子类中根据需要设置不同工作目录和环境,其中,dir默认为系统“user.dir”变量值,environment使用系统默认的环境。

通过interval与lastTime属性来检查,是否有必要重新执行一次,如果是就执行,否则重置退出状态码exitCode为0,正常退出,可以在Shell类的run方法中看到:

通过runCommand方法就可以执行指定的Shell命令,它是Shell类的核心。在分析runCommand方法之前,先了解一下与Shell命令执行相关的环境信息。

当在Windows系统下,打开一个cmd窗口的时候,执行set命令,就能看到当前系统的环境变量的信息,如下所示:

这些环境变量的信息都是以键值对的形式出现的,当在操作系统上运行相关的应用程序的时候,其实就是在上述环境变量所设置的一个上下文中运行,环境是应用程序运行不可缺少的条件。你在Unix系统中执行env命令,同样也能得到与上面类似的键值对的环境变量信息。

所以,org.apache.hadoop.util.Shell作为Shell命令的抽象,一定要获取到当前所在操作系统(Unix系统) 的环境变量,在这样一个上下文中,才能如同从Unix系统中输入执行Shell命令进行执行一样。

在Java中,实现了一个java.lang.ProcessBuilder类,该类能够创建一个操作系统的进程,通过为该进程设置运行环境变量,从而启动进行执行。默认情况下ProcessBuilder类已经实现了设置当前操作系统环境的功能,可以通过environment()方法查看它的实例所具有的环境信息,这等价于使用System.getenv()获取到的环境变量,都是以键值对的形式存在于ProcessBuilder类实例的上下文中。

下面,分析Shell类实现执行命令的过程,实现方法为runCommand,如下所示:

上面已经做了详细的注释,基本上阐明了一个命令行的执行过程。

在类中,还提供了一个static方法execCommand,为执行命令提供入口:

执行该方法,调用了另一个重载的execCommand方法,返回命令执行结果的信息。

注意,在Shell抽象类中并没有实现该怎样获取一个命令名称及其参数的方法,需要在实现类中给出,因此,在Shell类内部定义了一个静态内部类ShellCommandExecutor,该类实现了获取命令名称及其参数的方法。在上面方法execCommand中,调用了一个重载的execCommand方法,该方法中通过实例化一个ShellCommandExecutor类,来提供获取命令名称及其参数,进而构造一个ProcessBuilder实例,创建一个操作系统线程来执行命令行。

 

? extends Shell 

 

下面看实现Shell抽象类的一些子类的实现。

  • ShellCommandExecutor类

ShellComandExecutor类的实现如下所示:

  • DF类

org.apache.hadoop.fs.DF类实现了Unix系统中Shell命令df,用来获取磁盘使用情况的统计数据。该Shell实现类中定义域df命令操作相关的内容,可以从属性来看:

只需要实现Shell类定义的getExecString与parseExecResult方法即可。比较简单,getExecString方法实现如下:

该方法返回的字符串数组,用来构造一个ProcessBuilder进程实例。

parseExecResult方法实现如下所示:

  • DU类

DU类实现了Unix的du命令,显示目录或者文件大小的信息,具体实现可以参考org.apache.hadoop.fs.DU类,这里跳过。

  • CygPathCommand类

CygPathCommand类是org.apache.hadoop.fs.FileUtil类的一个内部静态类,实现了Windows系统上模拟Unix系统的Cygwin系统的cygpath命令,这里跳过。

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值