zoukankan      html  css  js  c++  java
  • 大数据时代之hadoop(二):hadoop脚本解析

    “兵马未动,粮草先行”,要想深入的了解hadoop,我觉得启动或停止hadoop的脚本是必须要先了解的。说到底,hadoop就是一个分布式存储和计算框架,但是这个分布式环境是如何启动,管理的呢,我就带着大家先从脚本入手吧。说实话,hadoop的启动脚本写的真好,里面考虑的地方非常周全(比如说路径中有空格,软连接等)。

    1、hadoop脚本简单介绍

       hadoop的脚本分布在$HADOOP_HOME下面的bin目录下和conf文件夹下,主要介绍如下:

    bin目录下
            hadoop                 hadoop底层核心脚本,所有分布式程序最终都是通过这个脚本启动的。
    hadoop-config.sh       基本别的脚本都会内嵌调用这个脚本,这个脚本作用就是解析命令行可选参数(--config :hadoop conf文件夹路径 和--hosts)
    hadoop-daemon.sh       启动或停止本机command参数所指定的分布式程序,通过调用hadoop脚本实现。
    hadoop-daemons.sh      启动所有机器上的hadoop分布式程序,通过调用slaves.sh实现。
    slaves.sh              在所有的机器上运行一组指定的命令(通过ssh无密码登陆),供上层使用。
    start-dfs.sh           在本机启动namenode,在slaves机器上启动datanode,在master机器上启动secondarynamenode,通过调用 hadoop-daemon.sh和hadoop-daemons.sh实现。
    start-mapred.sh        在本机启动jobtracker,在slaves机器上启动tasktracker,通过调用hadoop-daemon.sh和hadoop-daemons.sh实现。
    start-all.sh           启动所有分布式hadoop程序,通过调用start-dfs.sh和start-mapred.sh实现。
    start-balancer.sh      启动hadoop分布式环境复杂均衡调度程序,平衡各节点存储和处理能力。
    还有几个stop 脚本,就不用详细说了。


    conf目录下
    hadoop-env.sh          配置hadoop运行时所需要的一些参数变量,比如JAVA_HOME,HADOOP_LOG_DIR,HADOOP_PID_DIR等。

     

    2、脚本的魅力(详细解释)

    hadoop的脚本写的真好,不服不行,从中学习到了好多知识。
     

    2.1、hadoop-config.sh

     这个脚本比较简单,而且基本其他脚本都内嵌通过“. $bin/hadoop-config.sh”的形式调用此脚本,所以这个脚本就不用在第一行声明解释权,因为这种调用方式类似于把此脚本内容复制到父脚本里在同一个解释器里面运行。

         这个脚本主要做三部分内容:
     
    1、软连接解析和绝对路径解析
    1. #软连接解析  
    2. this="$0"  
    3. while [ -h "$this" ]; do  
    4.   ls=`ls -ld "$this"`  
    5.   link=`expr "$ls" : '.*-> (.*)$'`  
    6.   if expr "$link" : '.*/.*' > /dev/null; then  
    7.     this="$link"  
    8.   else  
    9.     this=`dirname "$this"`/"$link"  
    10.   fi  
    11. done  
    12.   
    13. #绝对路径解析  
    14. # convert relative path to absolute path  
    15. bin=`dirname "$this"`  
    16. script=`basename "$this"`  
    17. bin=`cd "$bin"; pwd`  
    18. this="$bin/$script"  
    19.   
    20. # the root of the Hadoop installation  
    21. export HADOOP_HOME=`dirname "$this"`/..  

    2、命令行可选参数--config解析并赋值
    1. #check to see if the conf dir is given as an optional argument  
    2. if [ $# -gt 1 ]  
    3. then  
    4.     if [ "--config" = "$1" ]  
    5.       then  
    6.           shift  
    7.           confdir=$1  
    8.           shift  
    9.           HADOOP_CONF_DIR=$confdir  
    10.     fi  
    11. fi  

    3、命令行可选参数--config解析并赋值
    1. #check to see it is specified whether to use the slaves or the  
    2. # masters file  
    3. if [ $# -gt 1 ]  
    4. then  
    5.     if [ "--hosts" = "$1" ]  
    6.     then  
    7.         shift  
    8.         slavesfile=$1  
    9.         shift  
    10.         export HADOOP_SLAVES="${HADOOP_CONF_DIR}/$slavesfile"  
    11.     fi  
    12. fi  
     

    2.2、hadoop

     
        此脚本是hadoop脚本的核心,变量的设置,程序的启动都是通过这个脚本做的。
     
    1、声明使用方法
    1. # if no args specified, show usage  
    2. if [ $# = 0 ]; then  
    3.   echo "Usage: hadoop [--config confdir] COMMAND"  
    4.   echo "where COMMAND is one of:"  
    5.   echo "  namenode -format     format the DFS filesystem"  
    6.   echo "  secondarynamenode    run the DFS secondary namenode"  
    7.   echo "  namenode             run the DFS namenode"  
    8.   echo "  datanode             run a DFS datanode"  
    9.   echo "  dfsadmin             run a DFS admin client"  
    10.   echo "  mradmin              run a Map-Reduce admin client"  
    11.   echo "  fsck                 run a DFS filesystem checking utility"  
    12.   echo "  fs                   run a generic filesystem user client"  
    13.   echo "  balancer             run a cluster balancing utility"  
    14.   echo "  jobtracker           run the MapReduce job Tracker node"   
    15.   echo "  pipes                run a Pipes job"  
    16.   echo "  tasktracker          run a MapReduce task Tracker node"   
    17.   echo "  job                  manipulate MapReduce jobs"  
    18.   echo "  queue                get information regarding JobQueues"   
    19.   echo "  version              print the version"  
    20.   echo "  jar <jar>            run a jar file"  
    21.   echo "  distcp <srcurl<desturl> copy file or directories recursively"  
    22.   echo "  archive -archiveName NAME <src>* <dest> create a hadoop archive"  
    23.   echo "  daemonlog            get/set the log level for each daemon"  
    24.   echo " or"  
    25.   echo "  CLASSNAME            run the class named CLASSNAME"  
    26.   echo "Most commands print help when invoked w/o parameters."  
    27.   exit 1  
    28. fi  

    2、设置java运行环境

            代码简单,就不写出来了,包括JAVA_HOME,JAVA_HEAP_MAX,CLASSPATH,HADOOP_LOG_DIR,HADOOP_POLICYFILE。其中用到了设置IFS-储界定符号的环境变量,默认值是空白字符(换行,制表符或者空格)。

     

    3、根据cmd设置运行时class

    1. # figure out which class to run  
    2. if [ "$COMMAND" = "namenode" ] ; then  
    3.   CLASS='org.apache.hadoop.hdfs.server.namenode.NameNode'  
    4.   HADOOP_OPTS="$HADOOP_OPTS $HADOOP_NAMENODE_OPTS"  
    5. elif [ "$COMMAND" = "secondarynamenode" ] ; then  
    6.   CLASS='org.apache.hadoop.hdfs.server.namenode.SecondaryNameNode'  
    7.   HADOOP_OPTS="$HADOOP_OPTS $HADOOP_SECONDARYNAMENODE_OPTS"  
    8. elif [ "$COMMAND" = "datanode" ] ; then  
    9.   CLASS='org.apache.hadoop.hdfs.server.datanode.DataNode'  
    10.   HADOOP_OPTS="$HADOOP_OPTS $HADOOP_DATANODE_OPTS"  
    11. elif [ "$COMMAND" = "fs" ] ; then  
    12.   CLASS=org.apache.hadoop.fs.FsShell  
    13.   HADOOP_OPTS="$HADOOP_OPTS $HADOOP_CLIENT_OPTS"  
    14. elif [ "$COMMAND" = "dfs" ] ; then  
    15.   CLASS=org.apache.hadoop.fs.FsShell  
    16.   HADOOP_OPTS="$HADOOP_OPTS $HADOOP_CLIENT_OPTS"  
    17. elif [ "$COMMAND" = "dfsadmin" ] ; then  
    18.   CLASS=org.apache.hadoop.hdfs.tools.DFSAdmin  
    19.   HADOOP_OPTS="$HADOOP_OPTS $HADOOP_CLIENT_OPTS"  
    20. elif [ "$COMMAND" = "mradmin" ] ; then  
    21.   CLASS=org.apache.hadoop.mapred.tools.MRAdmin  
    22.   HADOOP_OPTS="$HADOOP_OPTS $HADOOP_CLIENT_OPTS"  
    23. elif [ "$COMMAND" = "fsck" ] ; then  
    24.   CLASS=org.apache.hadoop.hdfs.tools.DFSck  
    25.   HADOOP_OPTS="$HADOOP_OPTS $HADOOP_CLIENT_OPTS"  
    26. elif [ "$COMMAND" = "balancer" ] ; then  
    27.   CLASS=org.apache.hadoop.hdfs.server.balancer.Balancer  
    28.   HADOOP_OPTS="$HADOOP_OPTS $HADOOP_BALANCER_OPTS"  
    29. elif [ "$COMMAND" = "jobtracker" ] ; then  
    30.   CLASS=org.apache.hadoop.mapred.JobTracker  
    31.   HADOOP_OPTS="$HADOOP_OPTS $HADOOP_JOBTRACKER_OPTS"  
    32. elif [ "$COMMAND" = "tasktracker" ] ; then  
    33.   CLASS=org.apache.hadoop.mapred.TaskTracker  
    34.   HADOOP_OPTS="$HADOOP_OPTS $HADOOP_TASKTRACKER_OPTS"  
    35. elif [ "$COMMAND" = "job" ] ; then  
    36.   CLASS=org.apache.hadoop.mapred.JobClient  
    37. elif [ "$COMMAND" = "queue" ] ; then  
    38.   CLASS=org.apache.hadoop.mapred.JobQueueClient  
    39. elif [ "$COMMAND" = "pipes" ] ; then  
    40.   CLASS=org.apache.hadoop.mapred.pipes.Submitter  
    41.   HADOOP_OPTS="$HADOOP_OPTS $HADOOP_CLIENT_OPTS"  
    42. elif [ "$COMMAND" = "version" ] ; then  
    43.   CLASS=org.apache.hadoop.util.VersionInfo  
    44.   HADOOP_OPTS="$HADOOP_OPTS $HADOOP_CLIENT_OPTS"  
    45. elif [ "$COMMAND" = "jar" ] ; then  
    46.   CLASS=org.apache.hadoop.util.RunJar  
    47. elif [ "$COMMAND" = "distcp" ] ; then  
    48.   CLASS=org.apache.hadoop.tools.DistCp  
    49.   CLASSPATH=${CLASSPATH}:${TOOL_PATH}  
    50.   HADOOP_OPTS="$HADOOP_OPTS $HADOOP_CLIENT_OPTS"  
    51. elif [ "$COMMAND" = "daemonlog" ] ; then  
    52.   CLASS=org.apache.hadoop.log.LogLevel  
    53.   HADOOP_OPTS="$HADOOP_OPTS $HADOOP_CLIENT_OPTS"  
    54. elif [ "$COMMAND" = "archive" ] ; then  
    55.   CLASS=org.apache.hadoop.tools.HadoopArchives  
    56.   CLASSPATH=${CLASSPATH}:${TOOL_PATH}  
    57.   HADOOP_OPTS="$HADOOP_OPTS $HADOOP_CLIENT_OPTS"  
    58. elif [ "$COMMAND" = "sampler" ] ; then  
    59.   CLASS=org.apache.hadoop.mapred.lib.InputSampler  
    60.   HADOOP_OPTS="$HADOOP_OPTS $HADOOP_CLIENT_OPTS"  
    61. else  
    62.   CLASS=$COMMAND  
    63. fi  


    4、设置本地库

    1. # setup 'java.library.path' for native-hadoop code if necessary  
    2. JAVA_LIBRARY_PATH=''  
    3. if [ -d "${HADOOP_HOME}/build/native" -o -d "${HADOOP_HOME}/lib/native" ]; then  
    4. #通过运行一个java 类来决定当前平台,挺有意思  
    5.   JAVA_PLATFORM=`CLASSPATH=${CLASSPATH} ${JAVA} -Xmx32m org.apache.hadoop.util.PlatformName | sed -e "s/ /_/g"`  
    6.     
    7.   if [ -d "$HADOOP_HOME/build/native" ]; then  
    8.     JAVA_LIBRARY_PATH=${HADOOP_HOME}/build/native/${JAVA_PLATFORM}/lib  
    9.   fi  
    10.     
    11.   if [ -d "${HADOOP_HOME}/lib/native" ]; then  
    12.     if [ "x$JAVA_LIBRARY_PATH" != "x" ]; then  
    13.       JAVA_LIBRARY_PATH=${JAVA_LIBRARY_PATH}:${HADOOP_HOME}/lib/native/${JAVA_PLATFORM}  
    14.     else  
    15.       JAVA_LIBRARY_PATH=${HADOOP_HOME}/lib/native/${JAVA_PLATFORM}  
    16.     fi  
    17.   fi  
    18. fi  


    5、运行分布式程序

    1. # run it  
    2. xec "$JAVA" $JAVA_HEAP_MAX $HADOOP_OPTS -classpath "$CLASSPATH" $CLASS "$@"  



    2.3、hadoop-daemon.sh       

           启动或停止本机command参数所指定的分布式程序,通过调用hadoop脚本实现,其实也挺简单的。

    1、声明使用方法

    1. usage="Usage: hadoop-daemon.sh [--config <conf-dir>] [--hosts hostlistfile] (start|stop) <hadoop-command> <args...>"  
    2.   
    3. # if no args specified, show usage  
    4. if [ $# -le 1 ]; then  
    5.   echo $usage  
    6.   exit 1  
    7. fi  


    2、设置环境变量


       
    首先内嵌运行hadoop-env.sh脚本,然后设置HADOOP_PID_DIR等环境变量。


    3、启动或停止程序

    1. case $startStop in  
    2.   
    3.   (start)  
    4.   
    5.     mkdir -p "$HADOOP_PID_DIR"  
    6.   
    7.     if [ -f $pid ]; then  
    8.     #如果程序已经启动的话,就停止,并退出。  
    9.       if kill -0 `cat $pid` > /dev/null 2>&1; then  
    10.         echo $command running as process `cat $pid`.  Stop it first.  
    11.         exit 1  
    12.       fi  
    13.     fi  
    14.   
    15.     if [ "$HADOOP_MASTER" != "" ]; then  
    16.       echo rsync from $HADOOP_MASTER  
    17.       rsync -a -e ssh --delete --exclude=.svn --exclude='logs/*' --exclude='contrib/hod/logs/*' $HADOOP_MASTER/ "$HADOOP_HOME"  
    18.     fi  
    19. # rotate 当前已经存在的log  
    20.     hadoop_rotate_log $log  
    21.     echo starting $command, logging to $log  
    22.     cd "$HADOOP_HOME"  
    23.     #通过nohup 和bin/hadoop脚本启动相关程序  
    24.     nohup nice -n $HADOOP_NICENESS "$HADOOP_HOME"/bin/hadoop --config $HADOOP_CONF_DIR $command "$@" > "$log" 2>&1 < /dev/null &  
    25.     #获取新启动的进程pid并写入到pid文件中  
    26.     echo $! > $pid  
    27.     sleep 1; head "$log"  
    28.     ;;  
    29.             
    30.   (stop)  
    31.   
    32.     if [ -f $pid ]; then  
    33.       if kill -0 `cat $pid` > /dev/null 2>&1; then  
    34.         echo stopping $command  
    35.         kill `cat $pid`  
    36.       else  
    37.         echo no $command to stop  
    38.       fi  
    39.     else  
    40.       echo no $command to stop  
    41.     fi  
    42.     ;;  
    43.   
    44.   (*)  
    45.     echo $usage  
    46.     exit 1  
    47.     ;;  
    48. esac  



    2.4、slaves.sh


         
    在所有的机器上运行一组指定的命令(通过ssh无密码登陆),供上层使用。


    1、声明使用方法

    1. usage="Usage: slaves.sh [--config confdir] command..."  
    2.   
    3. # if no args specified, show usage  
    4. if [ $# -le 0 ]; then  
    5.   echo $usage  
    6.   exit 1  
    7. fi  


    2、设置远程主机列表

    1. # If the slaves file is specified in the command line,  
    2. # then it takes precedence over the definition in   
    3. # hadoop-env.sh. Save it here.  
    4. HOSTLIST=$HADOOP_SLAVES  
    5.   
    6. if [ -f "${HADOOP_CONF_DIR}/hadoop-env.sh" ]; then  
    7.   . "${HADOOP_CONF_DIR}/hadoop-env.sh"  
    8. fi  
    9.   
    10. if [ "$HOSTLIST" = "" ]; then  
    11.   if [ "$HADOOP_SLAVES" = "" ]; then  
    12.     export HOSTLIST="${HADOOP_CONF_DIR}/slaves"  
    13.   else  
    14.     export HOSTLIST="${HADOOP_SLAVES}"  
    15.   fi  
    16. fi  


    3、分别在远程主机执行相关命令

    1. #挺重要,里面技术含量也挺高,对远程主机文件进行去除特殊字符和删除空行;对命令行进行空格替换,并通过ssh在目标主机执行命令;最后等待命令在所有目标主机执行完后,退出。  
    2. for slave in `cat "$HOSTLIST"|sed  "s/#.*$//;/^$/d"`; do  
    3.  ssh $HADOOP_SSH_OPTS $slave $"${@// /\ }"   
    4.    2>&1 | sed "s/^/$slave: /" &  
    5.  if [ "$HADOOP_SLAVE_SLEEP" != "" ]; then  
    6.    sleep $HADOOP_SLAVE_SLEEP  
    7.  fi  
    8. done  
    9.   
    10. wait  


    2.5、hadoop-daemons.sh

          启动远程机器上的hadoop分布式程序,通过调用slaves.sh实现。

    1、声明使用方法
     
    1. # Run a Hadoop command on all slave hosts.  
    2.   
    3. usage="Usage: hadoop-daemons.sh [--config confdir] [--hosts hostlistfile] [start|stop] command args..."  
    4.   
    5. # if no args specified, show usage  
    6. if [ $# -le 1 ]; then  
    7.   echo $usage  
    8.   exit 1  
    9. fi  

    2、在远程主机调用命令
    1. #通过salves.sh来实现  
    2. exec "$bin/slaves.sh" --config $HADOOP_CONF_DIR cd "$HADOOP_HOME" ; "$bin/hadoop-daemon.sh" --config $HADOOP_CONF_DIR "$@"  

    2.6、start-dfs.sh 

          本机(调用此脚本的主机)启动namenode,在slaves机器上启动datanode,在master机器上启动secondarynamenode,通过调用hadoop-daemon.sh和hadoop-daemons.sh实现。


    1、声明使用方式

    1. # Start hadoop dfs daemons.  
    2. # Optinally upgrade or rollback dfs state.  
    3. # Run this on master node.  
    4.   
    5. usage="Usage: start-dfs.sh [-upgrade|-rollback]"  


    2、启动程序

    1. # start dfs daemons  
    2. # start namenode after datanodes, to minimize time namenode is up w/o data  
    3. # note: datanodes will log connection errors until namenode starts  
    4. #在本机(调用此脚本的主机)启动namenode  
    5. "$bin"/hadoop-daemon.sh --config $HADOOP_CONF_DIR start namenode $nameStartOpt  
    6. #在slaves机器上启动datanode  
    7. "$bin"/hadoop-daemons.sh --config $HADOOP_CONF_DIR start datanode $dataStartOpt  
    8. #在master机器上启动secondarynamenode  
    9. "$bin"/hadoop-daemons.sh --config $HADOOP_CONF_DIR --hosts masters start secondarynamenode  


    2.7、start-mapred.sh 

         在本机(调用此脚本的主机)启动jobtracker,在slaves机器上启动tasktracker,通过调用hadoop-daemon.sh和hadoop-daemons.sh实现。
    1.  # start mapred daemons  
    2. # start jobtracker first to minimize connection errors at startup  
    3. #在本机(调用此脚本的主机)启动jobtracker  
    4. "$bin"/hadoop-daemon.sh --config $HADOOP_CONF_DIR start jobtracker  
    5. #在master机器上启动tasktracker  
    6. "$bin"/hadoop-daemons.sh --config $HADOOP_CONF_DIR start tasktracker  


    其他的脚本就都已经非常简单了,不用再详细说明了,只要看下,大致都能看懂。

     

    对了,最后再说下hadoop的脚本里面用的shell解释器的声明吧。

    1. #!/usr/bin/env bash  

    作用就是适应各种linux操作系统,能够找到 bash shell来解释执行本脚本,也挺有用的。

  • 相关阅读:
    UVA 1386 Cellular Automaton
    ZOJ 3331 Process the Tasks
    CodeForces 650B Image Preview
    CodeForces 650A Watchmen
    CodeForces 651B Beautiful Paintings
    CodeForces 651A Joysticks
    HUST 1601 Shepherd
    HUST 1602 Substring
    HUST 1600 Lucky Numbers
    POJ 3991 Seinfeld
  • 原文地址:https://www.cnblogs.com/xmzzp/p/4177519.html
Copyright © 2011-2022 走看看