HADOOP1.0.3的start-dfs.sh系列脚本分析

熟悉脚本的启动过程,也就熟悉了hadoop的执行过程。所以研究并学习hadoop的脚本启动过程是非常有意义的。

对shell命令不是太熟悉,学的比较辛苦,里面还有些地方不明白,或者有错误的地方,希望如果有错误,能有人帮我指出来,谢谢。

(1)start-dfs.sh脚本

1)说明

start-dfs.sh可以单独运行,也可以启动start-all.sh时启动dfs进程。

start-dfs.sh的作用在于启动主节点的namenode,启动secondnamenode,以及各从节点的datanode进程。

脚本注释中有以下三句话:

start-dfs支持upgrage和rollback两个参数,来更改系统的状态。其中upgrage用于升级hdfs文件系统;如果升级失败,可以用rollback对系统进行回滚。具体情况还不太明了。

最后,Run this on master node说明了必须在namenode进程运行的节点上运行该脚本。如果不在core-size.xml文件定义的fs.default.name变量的机器名运行start-dfs.sh或者start-daemon.sh或者hadoop namenode,是无法成功启动namenode守护进程的。已经经过验证。stop-dfs也是一样的。原因:在hadoop脚本中可以看出namenode进程是在本地启动的,所以如果不在core-site.xml定义的节点上运行start-dfs脚本,不会ssh到该节点上去启动namenode。这部分在后续会进行介绍。

2)脚本执行过程

由于脚本不长,而且其它脚本前面的处理也一致,所以对这个脚本作详细说明。后面的几个脚本就挑主要部分进行解释。

#说明:定义usage变量,即start-dfs.sh的使用说明,在后面的内容可以看到,当参数输入错误时,会打印该消息。

usage=”Usage: start-dfs.sh[-upgrade|-rollback]”

 

#说明:定义bin变量,即hadoop home目录中bin所在目录,也即运行start-dfs所在的目录。写这段脚本的作用在于,当不是在bin目录下运行该脚本时,采用绝对路径的方式,获取hadoop home目录,并在后面的脚本中,使用该路径来读取配置文件、运行其它脚本等。

bin=`dirname”$0″`

bin=`cd”$bin”; pwd`

 

#说明:运行配置脚本配置脚本主要定义了一些环境变量;并且得到HADOOP根目录,变量名为:HADOOP_PREFIX。(HADOOP_HOME环境变量已经过时)

if [ -e”$bin/../libexec/hadoop-config.sh” ]; then

  .”$bin”/../libexec/hadoop-config.sh

else

  . “$bin/hadoop-config.sh”

fi

 

#说明:处理脚本命令的参数。如果参数个数>=1,将第一个参数赋值给nameStartOpt变量。如果该变量不为-upgrage-rollback中的任何一个,就打印usage变量消息(前面第一行就是usage的变量定义),并且退出,不再继续执行。

# get arguments

if [ $# -ge 1 ]; then

    nameStartOpt=$1

    shift

    case $nameStartOpt in

      (-upgrade)

        ;;

      (-rollback)

        dataStartOpt=$nameStartOpt

        ;;

      (*)

         echo $usage

         exit 1

        ;;

    esac

fi

 

#说明:启动dfs的所有后台进程。

# start dfs daemons

# start namenode afterdatanodes, to minimize time namenode is up w/o data

# note: datanodes willlog connection errors until namenode starts

#说明:首先运行hadoop-daemon.sh脚本,通过参数’start namenode’启动namenode,后面将介绍hadoop-daemons.sh脚本介绍namenode的启动脚本的执行过程。

“$bin”/hadoop-daemon.sh–config $HADOOP_CONF_DIR start namenode $nameStartOpt

#说明:然后运行hadoop-daemons.sh脚本,通过参数’start datanode启动所有的datanode,后面将介绍hadoop-daemons.sh脚本介绍datanode的启动脚本的执行过程。

“$bin”/hadoop-daemons.sh–config $HADOOP_CONF_DIR start datanode $dataStartOpt

#说明:最后运行hadoop-daemons.sh脚本,通过参数’—hosts masters start secondarynamenode启动secondarynamenode,后面将介绍hadoop-daemons.sh脚本介绍secondarynamenode的启动脚本的执行过程。

“$bin”/hadoop-daemons.sh–config $HADOOP_CONF_DIR –hosts masters start secondarynamenode

(2)hadoop-daemon.sh脚本

前面三个步骤同上:定义用法说明和脚本的绝对路径、运行配置脚本、处理参数。由于脚本的参数较为重要,首先说明脚本的使用方法。

1)传入参数说明

#说明:定义startStop变量为第一个参数的值。在start-dfs.sh脚本中,调用该脚本时,传入的为’start’。该脚本仅支持startstop两种。

# get arguments

startStop=$1

#说明:在不了解参数个数和当前要使用的参数个数为第几个的情况,采用shift操作,将使用的参数出栈一位,原来的第二位参数变为第一个,后面仍然用$1来获取本来的第二个参数。

在这里,将start-dfs.sh脚本中,调用该脚本时,传的’namenode’作为command变量的值。

shift

command=$1

shift

2)该脚本使用说明

Usage: hadoop-daemon.sh[–config <conf-dir>] [–hosts hostlistfile] (start|stop)<hadoop-command> <args…>

说明:

–config <conf-dir>指定conf目录的路径;

–hosts hostlistfile:指定hosts,在slaves.sh脚本中,会ssh到该文件中配置的节点上去执行操作。如果没有定义该参数,则默认sshslaves文件中定义的节点上去启动后台进程;如果定义该参数,则到定义的机器上去启动后台进程。在start-dfs.sh中,secondarynamenode的启动,就是通过参数—hosts masters来制定获取目的机器的配置文件。

2)确认是否运行secure datanode

作用暂不清楚。

#说明:if中的条件用于判断是否为secure datanode设置,如果是,则后面的三个变量均定义为安全的变量。

if [“$command” == “datanode” ] && [ “$EUID”-eq 0 ] && [ -n “$HADOOP_SECURE_DN_USER” ]; then

  exportHADOOP_PID_DIR=$HADOOP_SECURE_DN_PID_DIR

  exportHADOOP_LOG_DIR=$HADOOP_SECURE_DN_LOG_DIR

  export HADOOP_IDENT_STRING=$HADOOP_SECURE_DN_USER  

fi

3)日志目录的创建和处理

#说明:获取日志路径

# get log directory

if [“$HADOOP_LOG_DIR” = “” ]; then

  exportHADOOP_LOG_DIR=”$HADOOP_HOME/logs”

fi

 

#说明:mkdir –p创建上层遗失目录。即如果该目录的上层目录也没有,就创建该上层目录。

mkdir -p”$HADOOP_LOG_DIR”

 

#说明$? —-上一个代码或者shell程序在shell中退出的情况,如果正常退出则返回0,反之为非0值。这里的作用,在于判断log目录中是否可以创建文件并进行文件写操作。

touch$HADOOP_LOG_DIR/.hadoop_test > /dev/null 2>&1

TEST_LOG_DIR=$?

#说明:目的在于测试log dir是否创建成功?即用户是否有权限?如果有,就删除该测试文件。

if [“${TEST_LOG_DIR}” = “0” ]; then

  rm -f $HADOOP_LOG_DIR/.hadoop_test

#说明:如果没有,就修改该目录的属性

else

  chown $HADOOP_IDENT_STRING $HADOOP_LOG_DIR

fi

#说明:设置log变量为.out文件名

log=$HADOOP_LOG_DIR/hadoop-$HADOOP_IDENT_STRING-$command-$HOSTNAME.out

4)设置pid变量用于存放进程的进程id号

pid的作用在于,判断namenode或者datanode等守护进程是否已经运行。如果已经运行,则打印消息说明已运行;如果没有,则启动守护进程,并将进程id存放在pid文件中,用于下次启动的判断。该过程在start命令的处理流程中。

#说明:获取系统用户名,并存放在HADOOP_IDENT_STRING变量中

if [“$HADOOP_IDENT_STRING” = “” ]; then

  export HADOOP_IDENT_STRING=”$USER”

fi

#说明:如果没有定义pid文件存放的目录,就设置为/tmp目录

if [“$HADOOP_PID_DIR” = “” ]; then

  HADOOP_PID_DIR=/tmp

Fi

#说明:设置pid文件名。根据当前启动的守护进程名称不同而不同。在start-dfs.sh中调用该进程,则pid文件名为/tmp/hadoop-gtl-namenode.pid

pid=$HADOOP_PID_DIR/hadoop-$HADOOP_IDENT_STRING-$command.pid

#说明:设置pid文件名。根据当前启动的守护进程名称不同而不同。在start-dfs.sh中调用该进程,则pid文件名为/tmp/hadoop-gtl-namenode.pid

pid=$HADOOP_PID_DIR/hadoop-$HADOOP_IDENT_STRING-$command.pid

5)启动或停止服务处理(这里只介绍启动)

#说明:在传入参数说明中,已经介绍了startStop参数的定义。在这里,为start,即启动。

case $startStop in

 

  (start)

#说明:创建HADOOP_PID_DIR所定义的pid文件存放的目录

    mkdir -p “$HADOOP_PID_DIR”

#说明:如果前面定义的pid变量为文件,则判断当前进程是否存在。如果已经存在,则打印消息,说明服务以及启动,如果要重新启动,需要先停止服务。

if [ -f $pid ]; then

      if kill -0 `cat $pid` > /dev/null2>&1; then

        echo $command running as process `cat$pid`.  Stop it first.

        exit 1

      fi

    fi

#说明:如果定义了HADOOP_MASTER变量,则将日志作镜像备份。其中hadoop_rotate_log是这个脚本中定义的函数,具体可参考hadoop-daemon.sh全文。

    if [ “$HADOOP_MASTER” !=”” ]; then

      echo rsync from $HADOOP_MASTER

      rsync -a -e ssh –delete –exclude=.svn–exclude=’logs/*’ –exclude=’contrib/hod/logs/*’ $HADOOP_MASTER/”$HADOOP_HOME”

fi

    hadoop_rotate_log $log

    echo starting $command, logging to $log

#说明:进入hadoop根目录,并在系统后台运行hadoop脚本,传入参数为namenode及其参数。并将消息输出到.out日志文件中。真正调用namenode执行实例的内容在hadoop脚本中。

    cd “$HADOOP_PREFIX”

nohup nice -n$HADOOP_NICENESS “$HADOOP_PREFIX”/bin/hadoop –config$HADOOP_CONF_DIR $command “$@” > “$log” 2>&1 </dev/null &

#说明:记录该进程的pid,并写入pid变量定义的文件中。

echo $! > $pid

#说明:打印log文件的前10行消息,如果没有错误,则没有消息;如果有错误,则会输出错误信息。

sleep 1; head”$log”

    ;;

 

(3)hadoop-daemons.sh脚本

前面三个步骤同上:定义用法说明和脚本的绝对路径、运行配置脚本、处理参数。

最后执行以下操作:

#说明:运行slaves.sh,为ssh到各datanode节点和secondarynamenode节点上;

如果是start-dfs调用该脚本传入start datanode来启动datanode服务,会在datanode节点上运行hadoop-daemon.sh start datanode命令

如果是start-dfs调用该脚本传入start secondarynamenode来启动secondarynamenode服务,会在masters定义的节点上运行hadoop-daemon.sh  –host masters startsecondarynamenode命令

exec”$bin/slaves.sh” –config $HADOOP_CONF_DIR cd”$HADOOP_HOME” \; “$bin/hadoop-daemon.sh” –config$HADOOP_CONF_DIR “$@”

(4)slaves.sh脚本

前面的步骤同上,不予解释。

1)HADOOP_SLAVES的定义

#说明:如果该变量没有定义,则默认为slaves文件。在hadoop-config文件中,关于HADOOP_SLAVES变量,有专门的处理:如果有—host参数,则HADOOP_SLAVES= ${HADOOP_CONF_DIR}目录下的—host参数后面的参数值。所以在secondarynamenode中,定义的master文件,即为启动secondarynamenode的节点定义文件,而不是通常理解的namenode的启动节点。

if [“$HOSTLIST” = “” ]; then

  if [ “$HADOOP_SLAVES” =”” ]; then

    export HOSTLIST=”${HADOOP_CONF_DIR}/slaves”

  else

    exportHOSTLIST=”${HADOOP_SLAVES}”

  fi

fi

2)ssh到各slaves节点上

#说明:读取HADOOP_SLAVES变量的文件的每个slave节点,并用ssh登录到slave节点。

#说明:不匹配注释行和空行。

for slave in `cat”$HOSTLIST”|sed “s/#.*$//;/^$/d”`; do

 #说明:这一段脚本的作用在于ssh到目标host后,将在目标节点上的消息打印,并以{hostname: }开头来打印消息。

ssh $HADOOP_SSH_OPTS$slave $”${@// /\\ }” \

   2>&1 | sed “s/^/$slave: /”&

if [“$HADOOP_SLAVE_SLEEP” != “” ]; then

   sleep $HADOOP_SLAVE_SLEEP

 fi

done

(5)hadoop脚本

这是hadoop所有脚本执行的核心。

前面的步骤同上,不予解释。

在这里有一部分的cygwin的环境变量的说明。这部分是用于兼容windows的cygwin环境而设的。不进行单独说明。

除了设置hadoop通用的变量外,在这个脚本中,还设置了java运行环境的参数。

本脚本主要的核心在于执行类的定义。

1)执行命令参数对应的执行类说明

#说明:根据命令参数,指定运行的类

# figure out which classto run

#说明:’hadoop classpath’,打印classpath环境变量,并退出程序。

if [“$COMMAND” = “classpath” ] ; then

  if $cygwin; then

    CLASSPATH=`cygpath -p -w”$CLASSPATH”`

  fi

  echo $CLASSPATH

  exit

#说明:org.apache.hadoop.hdfs.server包,提供hdfs后台服务运行的类。

#说明:’hadoop namenode’,设置运行类为NameNode类,会首先进入该类的main()函数。

elif [“$COMMAND” = “namenode” ] ; then

  CLASS=’org.apache.hadoop.hdfs.server.namenode.NameNode’

  HADOOP_OPTS=”$HADOOP_OPTS$HADOOP_NAMENODE_OPTS”

#说明:’hadoop secondarynamenode’,设置运行类为SecondaryNameNode类。

elif [“$COMMAND” = “secondarynamenode” ] ; then

 CLASS=’org.apache.hadoop.hdfs.server.namenode.SecondaryNameNode’

  HADOOP_OPTS=”$HADOOP_OPTS$HADOOP_SECONDARYNAMENODE_OPTS”

#说明:’hadoop datanode’,设置运行类为DataNode类。

elif [“$COMMAND” = “datanode” ] ; then

 CLASS=’org.apache.hadoop.hdfs.server.datanode.DataNode’

#说明:是否启动安全运行Datanode服务的配置。

  if [ “$starting_secure_dn” =”true” ]; then

    HADOOP_OPTS=”$HADOOP_OPTS -jvm server$HADOOP_DATANODE_OPTS”

  else

    HADOOP_OPTS=”$HADOOP_OPTS -server$HADOOP_DATANODE_OPTS”

  Fi

#说明:org.apache.hadoop.fs包,提供文件系统上的文件访问操作类。

#说明:’hadoop fs’,设置运行类为FSShell类,用于文件系统上的操作。

elif [ “$COMMAND”= “fs” ] ; then

  CLASS=org.apache.hadoop.fs.FsShell

  HADOOP_OPTS=”$HADOOP_OPTS$HADOOP_CLIENT_OPTS”

#说明:’hadoop dfs’,设置运行类也为FSShell类,用于在分布式文件系统上的操作。

#说明:网上查询’hadoop fs’’hadoop dfs’这两个命令的区别在于一个为抽象文件系统,一个为分布是文件系统。但是从这里可以判断,其实就这两个命令而言,没有任何区别。

elif [ “$COMMAND”= “dfs” ] ; then

  CLASS=org.apache.hadoop.fs.FsShell

  HADOOP_OPTS=”$HADOOP_OPTS$HADOOP_CLIENT_OPTS”

#说明:org.apache.hadoop.hdfs/mapred. tools包,提供工具类。

#说明:’hadoop dfsadmin’,设置运行类为DFSAdmin类,用于管理dfs

elif [“$COMMAND” = “dfsadmin” ] ; then

  CLASS=org.apache.hadoop.hdfs.tools.DFSAdmin

  HADOOP_OPTS=”$HADOOP_OPTS$HADOOP_CLIENT_OPTS”

#说明:’hadoop mradmin’,设置运行类为MRAdmin类,用于管理mapred

elif [“$COMMAND” = “mradmin” ] ; then

  CLASS=org.apache.hadoop.mapred.tools.MRAdmin

  HADOOP_OPTS=”$HADOOP_OPTS $HADOOP_CLIENT_OPTS”

#说明:’hadoop fsck’,设置运行类为DFSck类,用于检查fs文件系统?

elif [“$COMMAND” = “fsck” ] ; then

  CLASS=org.apache.hadoop.hdfs.tools.DFSck

  HADOOP_OPTS=”$HADOOP_OPTS$HADOOP_CLIENT_OPTS”

#说明:’hadoop balancer’,设置运行类为Balancer类,集群负载均衡服务?

elif [“$COMMAND” = “balancer” ] ; then

 CLASS=org.apache.hadoop.hdfs.server.balancer.Balancer

  HADOOP_OPTS=”$HADOOP_OPTS$HADOOP_BALANCER_OPTS”

#说明:’hadoop fetchdt’,设置运行类为DelegationTokenFetcher类?

elif [“$COMMAND” = “fetchdt” ] ; then

  CLASS=org.apache.hadoop.hdfs.tools.DelegationTokenFetcher

#说明:org.apache.hadoop.mapred包,提供mapreduce实现的类。

#说明:’hadoop jobtracker’,设置运行类为JpbTracker类,用于启动jobtracker服务。

elif [“$COMMAND” = “jobtracker” ] ; then

  CLASS=org.apache.hadoop.mapred.JobTracker

  HADOOP_OPTS=”$HADOOP_OPTS$HADOOP_JOBTRACKER_OPTS”

#说明:’hadoop historyserver’,设置运行类为JobHistoryServer?

elif [“$COMMAND” = “historyserver” ] ; then

 CLASS=org.apache.hadoop.mapred.JobHistoryServer

  HADOOP_OPTS=”$HADOOP_OPTS$HADOOP_JOB_HISTORYSERVER_OPTS”

#说明:’hadoop tasktracker’,设置运行类为TaskTracker类,用于启动tasktracker服务。

elif [“$COMMAND” = “tasktracker” ] ; then

  CLASS=org.apache.hadoop.mapred.TaskTracker

  HADOOP_OPTS=”$HADOOP_OPTS$HADOOP_TASKTRACKER_OPTS”

#说明:’hadoop job’,设置运行类为JobClient

elif [“$COMMAND” = “job” ] ; then

  CLASS=org.apache.hadoop.mapred.JobClient

  HADOOP_OPTS=”$HADOOP_OPTS$HADOOP_CLIENT_OPTS”

#说明:’hadoop queue’,设置运行类为JobQueueClient

elif [“$COMMAND” = “queue” ] ; then

  CLASS=org.apache.hadoop.mapred.JobQueueClient

  HADOOP_OPTS=”$HADOOP_OPTS$HADOOP_CLIENT_OPTS”

#说明:’hadoop pipes’,设置运行类为Submitter

elif [“$COMMAND” = “pipes” ] ; then

 CLASS=org.apache.hadoop.mapred.pipes.Submitter

  HADOOP_OPTS=”$HADOOP_OPTS$HADOOP_CLIENT_OPTS”

#说明:org.apache.hadoop.util包,提供了通用的工具类。

#说明:’hadoop version’,设置运行类为VersionInfo类,用于打印hadoop版本信息。

elif [“$COMMAND” = “version” ] ; then

  CLASS=org.apache.hadoop.util.VersionInfo

  HADOOP_OPTS=”$HADOOP_OPTS$HADOOP_CLIENT_OPTS”

#说明:’hadoop jar’设置运行类为RunJar类,用于运行外部jar包。

elif [“$COMMAND” = “jar” ] ; then

  CLASS=org.apache.hadoop.util.RunJar

  HADOOP_OPTS=”$HADOOP_OPTS$HADOOP_CLIENT_OPTS”

#说明:’hadoop distcp’设置运行类为DistCp?

elif [“$COMMAND” = “distcp” ] ; then

  CLASS=org.apache.hadoop.tools.DistCp

  CLASSPATH=${CLASSPATH}:${TOOL_PATH}

  HADOOP_OPTS=”$HADOOP_OPTS$HADOOP_CLIENT_OPTS”

#说明:’hadoop daemonlog设置运行类为LogLevel?

elif [“$COMMAND” = “daemonlog” ] ; then

  CLASS=org.apache.hadoop.log.LogLevel

  HADOOP_OPTS=”$HADOOP_OPTS$HADOOP_CLIENT_OPTS”

#说明:’hadoop archive设置运行类为HadoopArchives?

elif [“$COMMAND” = “archive” ] ; then

  CLASS=org.apache.hadoop.tools.HadoopArchives

  CLASSPATH=${CLASSPATH}:${TOOL_PATH}

  HADOOP_OPTS=”$HADOOP_OPTS$HADOOP_CLIENT_OPTS”

#说明:’hadoop sampler设置运行类为InputSampler?

elif [“$COMMAND” = “sampler” ] ; then

 CLASS=org.apache.hadoop.mapred.lib.InputSampler

  HADOOP_OPTS=”$HADOOP_OPTS$HADOOP_CLIENT_OPTS”

else

  CLASS=$COMMAND

fi

2)运行执行类

#说明:通过java 类名类参数的的方式,来运行执行类。

exec “$JAVA”-Dproc_$COMMAND $JAVA_HEAP_MAX $HADOOP_OPTS -classpath “$CLASSPATH”$CLASS “$@”

    原文作者:DFS
    原文地址: https://blog.csdn.net/aperson111/article/details/7942967
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞