第二章:小朱ノートhadoopのソースコード分析-スクリプト分析

20561 ワード

第二章:小朱ノートhadoopのソースコード分析-スクリプト分析


第一節:start-all.sh第二節:hadoop-config.sh第三節:hadoop-env.sh第四節:start-dfs.sh第五節:hadoop-daemon.sh第六節:hadoop-daemons.sh第七節:slaves.sh第八節:start-mapred.sh第九節:hadoop
 

第一節:start-all.sh


(1)内容:
# Start all hadoop daemons.  Run this on master node.

bin=`dirname "$0"`
bin=`cd "$bin"; pwd`

if [ -e "$bin/../libexec/hadoop-config.sh" ]; then
  . "$bin"/../libexec/hadoop-config.sh
else
  . "$bin/hadoop-config.sh"
fi

# start dfs daemons
"$bin"/start-dfs.sh --config $HADOOP_CONF_DIR

# start mapred daemons
"$bin"/start-mapred.sh --config $HADOOP_CONF_DIR

(2)このスクリプトを実行するディレクトリからインストールhadoopディレクトリの下にあるbinディレクトリを解析しhadoop-configを取得する.sh構成では、いくつかの変数に値を割り当て、hdfsとmapredを起動する起動スクリプトを実行します.
 
と書く
Start all hadoop daemons. Run this on master node.
 
 

第二節:hadoop-config.sh


(1)内容
# Allow alternate conf dir location.
if [ -e "${HADOOP_PREFIX}/conf/hadoop-env.sh" ]; then
  DEFAULT_CONF_DIR="conf"
else
  DEFAULT_CONF_DIR="etc/hadoop"
fi
HADOOP_CONF_DIR="${HADOOP_CONF_DIR:-$HADOOP_PREFIX/$DEFAULT_CONF_DIR}"

#check to see it is specified whether to use the slaves or the
# masters file
if [ $# -gt 1 ]
then
    if [ "--hosts" = "$1" ]
    then
        shift
        slavesfile=$1
        shift
        export HADOOP_SLAVES="${HADOOP_CONF_DIR}/$slavesfile"
    fi
fi

# hadoop-env.sh
if [ -f "${HADOOP_CONF_DIR}/hadoop-env.sh" ]; then
  . "${HADOOP_CONF_DIR}/hadoop-env.sh"
fi

 
 
(2)分析
いくつかの変数を割り当てます.これらの変数にはHADOOP_があります.HOME(hadoopのインストールディレクトリ)、HADOOP_CONF_DIR(hadoopのプロファイルディレクトリ)、HADOOP_SLAVES(--slavesが指定したファイルのアドレス).このスクリプトはまたhadoop-envを実行します.shスクリプトは、ユーザ構成に関する環境変数を設定します.

 


第三節:hadoop-env.sh


(1)内容
# The only required environment variable is JAVA_HOME.  All others are
# optional.  When running a distributed configuration it is best to
# set JAVA_HOME in this file, so that it is correctly defined on
# remote nodes.

# The java implementation to use.  Required.
export JAVA_HOME=/opt/java

# Extra Java CLASSPATH elements.  Optional.
# export HADOOP_CLASSPATH=

# The maximum amount of heap to use, in MB. Default is 1000.
export HADOOP_HEAPSIZE=2000

# Extra Java runtime options.  Empty by default.
# export HADOOP_OPTS=-server

# Command specific options appended to HADOOP_OPTS when specified
export HADOOP_NAMENODE_OPTS="-Dcom.sun.management.jmxremote $HADOOP_NAMENODE_OPTS"
export HADOOP_SECONDARYNAMENODE_OPTS="-Dcom.sun.management.jmxremote $HADOOP_SECONDARYNAMENODE_OPTS"
export HADOOP_DATANODE_OPTS="-Dcom.sun.management.jmxremote $HADOOP_DATANODE_OPTS"
export HADOOP_BALANCER_OPTS="-Dcom.sun.management.jmxremote $HADOOP_BALANCER_OPTS"
export HADOOP_JOBTRACKER_OPTS="-Dcom.sun.management.jmxremote $HADOOP_JOBTRACKER_OPTS"

 
 
(2)分析
Javaが実行する関連パラメータを設定します.たとえばJAVA_HOME変数(必須)、jvmを実行する最大ヒープスペースなど

第四節:start-dfs.sh


(1)内容
usage="Usage: start-dfs.sh [-upgrade|-rollback]"

.....

# start dfs daemons
# start namenode after datanodes, to minimize time namenode is up w/o data
# note: datanodes will log connection errors until namenode starts
"$bin"/hadoop-daemon.sh --config $HADOOP_CONF_DIR start namenode $nameStartOpt
"$bin"/hadoop-daemons.sh --config $HADOOP_CONF_DIR start datanode $dataStartOpt
"$bin"/hadoop-daemons.sh --config $HADOOP_CONF_DIR --hosts masters start secondarynamenode

 
 
(2)分析
このスクリプトはupgradeとrollbackの2つのオプションパラメータのみをサポートします.1つのパラメータはファイルシステムを更新するために使用され、もう1つはファイルシステムをロールバックします.次にnamenode、datanode、secondarynamenodeノードを起動します
 

第五節:hadoop-daemon.sh


(1)分析
 
と書く
HADOOP_CONF_DIRプロファイルディレクトリを選択します.デフォルトは${HADOOP_HOME}/confです.
HADOOP_LOG_DIRログファイルを格納するディレクトリ.デフォルトはPWDコマンドで生成されたディレクトリです
HADOOP_MASTER host:path where hadoop code should be rsync'd from
HADOOP_PID_DIR The pid files are stored./tmp by default.
HADOOP_IDENT_STRING A string representing this instance of hadoop. $USER by default
HADOOP_NICENESS The scheduling priority for daemons. Defaults to 0.
ステップ1:パラメータが1より小さいかどうかを判断し、小さい場合はこのスクリプトの使用ヘルプを印刷します.
# if no args specified, show usage
if [ $# -le 1 ]; then
  echo $usage
  exit 1
fi

ステップ2:hadoop-configを実行する.sh値変数を設定し、起動または停止のコマンドと関連パラメータを保存する
if [ -e "$bin/../libexec/hadoop-config.sh" ]; then
  . "$bin"/../libexec/hadoop-config.sh
else
  . "$bin/hadoop-config.sh"
fi

# get arguments
startStop=$1
shift
command=$1
shift

ステップ3:ロールバックログ関数hadoop_を定義するrotate_log
hadoop_rotate_log ()
{
    log=$1;
    num=5;
    if [ -n "$2" ]; then
	num=$2
    fi
    if [ -f "$log" ]; then # rotate logs
	while [ $num -gt 1 ]; do
	    prev=`expr $num - 1`
	    [ -f "$log.$prev" ] && mv "$log.$prev" "$log.$num"
	    num=$prev
	done
	mv "$log" "$log.$num";
    fi
}

 
ステップ4、hadoop-envを実行する.sh並列値環境変数
if [ -f "${HADOOP_CONF_DIR}/hadoop-env.sh" ]; then
  . "${HADOOP_CONF_DIR}/hadoop-env.sh"
fi

 
ステップ5、startまたはstopを実行し、start:namenodeのコマンドを起動するには、まずpidファイルを格納するディレクトリを作成し、pidを格納するファイルがすでに存在する場合は、namenodeノードがすでに実行されていることを示している場合は、起動中に停止します.その後、ログスクロール関数に基づいてログファイルを生成し、最後にniceでスケジューリング優先度に基づいてnamenodeを起動しますが、最終的な起動にはもう一つのスクリプトhadoopがあります.このスクリプトはすべてのノードを起動する究極のスクリプトで、main関数付きのクラスを選択してjavaで起動します.そうすれば、javaデーモンプロセスを起動する効果が得られます.このスクリプトは起動の重点であり、hadoopソースコードを分析する入り口でもあります.(1)pidのファイルを検証する
 mkdir -p "$HADOOP_PID_DIR"

    if [ -f $pid ]; then
      if kill -0 `cat $pid` > /dev/null 2>&1; then
        echo $command running as process `cat $pid`.  Stop it first.
        exit 1
      fi
    fi

(2)ログスクロール関数によるログファイルの生成
 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

(3)niceはスケジューリング優先度に従って起動する
    cd "$HADOOP_PREFIX"
    nohup nice -n $HADOOP_NICENESS "$HADOOP_PREFIX"/bin/hadoop --config $HADOOP_CONF_DIR $command "$@" > "$log" 2>&1 < /dev/null &
    echo $! > $pid

注意起動後、/tmpディレクトリに次のファイルが表示されます.これらのファイルには、kill操作に使用できるプロセス番号が保存されています.
と書く
-rw-rw-r-1 zhuhui zhui 6 3月6 17:25 hadoop-zhui-datanode.pid
-rw-rw-r--1 zhuhui zhui 6 3月6 17:25 hadoop-zhui-jobtracker.pid
-rw-rw-r-1 zhuhui zhui 6 3月6 17:25 hadoop-zhui-namenode.pid
-rw-rw-r-1 zhuhui zhui 6 3月6 17:25 hadoop-zhui-secondarynamenode.pid
-rw-rw-r--1 zhuhui zhui 6 3月6 17:25 hadoop-zhui-tasktracker.pid
stop stopコマンドは簡単な停止コマンドを実行しkill`cat$pid`操作を実行します
if [ -f $pid ]; then
      if kill -0 `cat $pid` > /dev/null 2>&1; then
        echo stopping $command
        kill `cat $pid`
      else
        echo no $command to stop
      fi
    else
      echo no $command to stop
    fi
    ;;

 
 

第六節:hadoop-daemons.sh


(1)内容
usage="Usage: hadoop-daemons.sh [--config confdir] [--hosts hostlistfile] [start|stop] command args..."

# if no args specified, show usage
if [ $# -le 1 ]; then
  echo $usage
  exit 1
fi

bin=`dirname "$0"`
bin=`cd "$bin"; pwd`

if [ -e "$bin/../libexec/hadoop-config.sh" ]; then
  . "$bin"/../libexec/hadoop-config.sh
else
  . "$bin/hadoop-config.sh"
fi

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

 
(2)分析
ハドop-daemonを通ります.shスクリプトを起動するには、その前にいくつかの特殊な処理を行っただけで、別のスクリプトslavesを実行します.sh
と書く
exec "$bin/slaves.sh"--config $HADOOP_CONF_DIR cd "$HADOOP_HOME"\; "$bin/hadoop-daemon.sh"--config $HADOOP_CONF_DIR "$@"
 
 

第七節:slaves.sh


(1)内容
# If the slaves file is specified in the command line,
# then it takes precedence over the definition in 
# hadoop-env.sh. Save it here.
HOSTLIST=$HADOOP_SLAVES

if [ -f "${HADOOP_CONF_DIR}/hadoop-env.sh" ]; then
  . "${HADOOP_CONF_DIR}/hadoop-env.sh"
fi

if [ "$HOSTLIST" = "" ]; then
  if [ "$HADOOP_SLAVES" = "" ]; then
    export HOSTLIST="${HADOOP_CONF_DIR}/slaves"
  else
    export HOSTLIST="${HADOOP_SLAVES}"
  fi
fi

for slave in `cat "$HOSTLIST"|sed  "s/#.*$//;/^$/d"`; do
 ssh $HADOOP_SSH_OPTS $slave $"${@// /\\ }" \
   2>&1 | sed "s/^/$slave: /" &
 if [ "$HADOOP_SLAVE_SLEEP" != "" ]; then
   sleep $HADOOP_SLAVE_SLEEP
 fi
done

wait

 
 
 
(2)分析
まず、ノードからすべてのホスト名(slavesファイル、またはプロファイルに構成されている)を見つけ、forループを介してsshリモートバックグラウンドで起動スクリプトプログラムを順次実行し、プログラムが完了するまで待機してshellスクリプトを終了します.したがって、このスクリプトの主な機能は、ノードから対応するノードを起動するすべてのスクリプトを実行することです.このスクリプト実行datanodeはslavesファイルからdatanodeノードを見つけ、secondarynamenodeはmasterファイルでノードホストを見つけます(start-dfs.shスクリプトで-hosts masterで指定します.そうしないとデフォルトでslavesファイルが見つかります.datanodeはデフォルトで見つかります).
 

第八節:start-mapred.sh


(1)内容
 
"$bin"/hadoop-daemon.sh --config $HADOOP_CONF_DIR start jobtracker
"$bin"/hadoop-daemons.sh --config $HADOOP_CONF_DIR start tasktracker

(2)分析
jobtrackerノードとtasktrackerノードをそれぞれ起動
 

第九節:hadoop


各ノードのサービスを開始したり、多くのコマンドやツールを実行したりすることができます.入力されたパラメータに基づいて、どのような機能が実行されるか(各ノードサービスの起動を含む)を決定します.
 
と書く
echo "Usage: hadoop [--config confdir] COMMAND"
echo "where COMMAND is one of:"
echo "namenode -format format the DFS filesystem"
echo "secondarynamenode run the DFS secondary namenode"
echo "namenode run the DFS namenode"
echo "datanode run a DFS datanode"
echo "dfsadmin run a DFS admin client"
echo "mradmin run a Map-Reduce admin client"
echo "fsck run a DFS filesystem checking utility"
echo "fs run a generic filesystem user client"
echo "balancer run a cluster balancing utility"
echo "fetchdt fetch a delegation token from the NameNode"
echo "jobtracker run the MapReduce job Tracker node"
echo "pipes run a Pipes job"
echo "tasktracker run a MapReduce task Tracker node"
echo "historyserver run job history servers as a standalone daemon"
echo "job manipulate MapReduce jobs"
echo "queue get information regarding JobQueues"
echo "version print the version"
echo "jar run a jar file"
echo "distcp copy file or directories recursively"
echo "archive -archiveName NAME -p * create a hadoop archive"
echo "classpath prints the class path needed to get the"
echo "Hadoop jar and the required libraries"
echo "daemonlog get/set the log level for each daemon"
echo "or"
echo "CLASSNAME run the class named CLASSNAME"
echo "Most commands print help when invoked w/o parameters."
exit 1
 
 
ステップ1:hadoop-configを実行する.sh設定値環境変数
 
if [ -e "$bin"/../libexec/hadoop-config.sh ]; then
  . "$bin"/../libexec/hadoop-config.sh
else
  . "$bin"/hadoop-config.sh
fi

 
 
ステップ2:cygwin環境かどうかを判断する
cygwin=false
case "`uname`" in
CYGWIN*) cygwin=true;;
esac

 
ステップ3:パラメータチェック
 
  namenode -format、secondarynamenode、namenode、datanode、dfsadmin、mradmin、fsck 、fs、balancer、fetchdt、jobtracker、pipes、tasktracker、historyserver、job、queue、version、jar <jar> 、distcp 、archive、classpath 、daemonlog 

 
ステップ4:java環境変数JAVA、JAVAを設定するHEAP_MAX、CLASSPATH
 
JAVA=$JAVA_HOME/bin/java
JAVA_HEAP_MAX=-Xmx1000m 

# CLASSPATH initially contains $HADOOP_CONF_DIR
CLASSPATH="${HADOOP_CONF_DIR}"
if [ "$HADOOP_USER_CLASSPATH_FIRST" != "" ] && [ "$HADOOP_CLASSPATH" != "" ] ; then
  CLASSPATH=${CLASSPATH}:${HADOOP_CLASSPATH}
fi
CLASSPATH=${CLASSPATH}:$JAVA_HOME/lib/tools.jar

# for developers, add Hadoop classes to CLASSPATH
if [ -d "$HADOOP_HOME/build/classes" ]; then
  CLASSPATH=${CLASSPATH}:$HADOOP_HOME/build/classes
fi
if [ -d "$HADOOP_HOME/build/webapps" ]; then
  CLASSPATH=${CLASSPATH}:$HADOOP_HOME/build
fi
if [ -d "$HADOOP_HOME/build/test/classes" ]; then
  CLASSPATH=${CLASSPATH}:$HADOOP_HOME/build/test/classes
fi
if [ -d "$HADOOP_HOME/build/tools" ]; then
  CLASSPATH=${CLASSPATH}:$HADOOP_HOME/build/tools
fi

 
 
 
ステップ5:ビジネスCLASS実行クラスを設定し、保存したコマンドに対応する起動javaクラスを選択する
# figure out which class to run
if [ "$COMMAND" = "classpath" ] ; then
  if $cygwin; then
    CLASSPATH=`cygpath -p -w "$CLASSPATH"`
  fi
  echo $CLASSPATH
  exit
elif [ "$COMMAND" = "namenode" ] ; then
  CLASS='org.apache.hadoop.hdfs.server.namenode.NameNode'
  HADOOP_OPTS="$HADOOP_OPTS $HADOOP_NAMENODE_OPTS"
elif [ "$COMMAND" = "secondarynamenode" ] ; then
  CLASS='org.apache.hadoop.hdfs.server.namenode.SecondaryNameNode'
  HADOOP_OPTS="$HADOOP_OPTS $HADOOP_SECONDARYNAMENODE_OPTS"
elif [ "$COMMAND" = "datanode" ] ; then
  CLASS='org.apache.hadoop.hdfs.server.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
elif [ "$COMMAND" = "fs" ] ; then
  CLASS=org.apache.hadoop.fs.FsShell
  HADOOP_OPTS="$HADOOP_OPTS $HADOOP_CLIENT_OPTS"
elif [ "$COMMAND" = "dfs" ] ; then
  CLASS=org.apache.hadoop.fs.FsShell
  HADOOP_OPTS="$HADOOP_OPTS $HADOOP_CLIENT_OPTS"
elif [ "$COMMAND" = "dfsadmin" ] ; then
  CLASS=org.apache.hadoop.hdfs.tools.DFSAdmin
  HADOOP_OPTS="$HADOOP_OPTS $HADOOP_CLIENT_OPTS"
elif [ "$COMMAND" = "mradmin" ] ; then
  CLASS=org.apache.hadoop.mapred.tools.MRAdmin
  HADOOP_OPTS="$HADOOP_OPTS $HADOOP_CLIENT_OPTS"
elif [ "$COMMAND" = "fsck" ] ; then
  CLASS=org.apache.hadoop.hdfs.tools.DFSck
  HADOOP_OPTS="$HADOOP_OPTS $HADOOP_CLIENT_OPTS"
elif [ "$COMMAND" = "balancer" ] ; then
  CLASS=org.apache.hadoop.hdfs.server.balancer.Balancer
  HADOOP_OPTS="$HADOOP_OPTS $HADOOP_BALANCER_OPTS"
elif [ "$COMMAND" = "fetchdt" ] ; then
  CLASS=org.apache.hadoop.hdfs.tools.DelegationTokenFetcher
elif [ "$COMMAND" = "jobtracker" ] ; then
  CLASS=org.apache.hadoop.mapred.JobTracker
  HADOOP_OPTS="$HADOOP_OPTS $HADOOP_JOBTRACKER_OPTS"
elif [ "$COMMAND" = "historyserver" ] ; then
  CLASS=org.apache.hadoop.mapred.JobHistoryServer
  HADOOP_OPTS="$HADOOP_OPTS $HADOOP_JOB_HISTORYSERVER_OPTS"
elif [ "$COMMAND" = "tasktracker" ] ; then
  CLASS=org.apache.hadoop.mapred.TaskTracker
  HADOOP_OPTS="$HADOOP_OPTS $HADOOP_TASKTRACKER_OPTS"
elif [ "$COMMAND" = "job" ] ; then
  CLASS=org.apache.hadoop.mapred.JobClient
  HADOOP_OPTS="$HADOOP_OPTS $HADOOP_CLIENT_OPTS"
elif [ "$COMMAND" = "queue" ] ; then
  CLASS=org.apache.hadoop.mapred.JobQueueClient
  HADOOP_OPTS="$HADOOP_OPTS $HADOOP_CLIENT_OPTS"
elif [ "$COMMAND" = "pipes" ] ; then
  CLASS=org.apache.hadoop.mapred.pipes.Submitter
  HADOOP_OPTS="$HADOOP_OPTS $HADOOP_CLIENT_OPTS"
elif [ "$COMMAND" = "version" ] ; then
  CLASS=org.apache.hadoop.util.VersionInfo
  HADOOP_OPTS="$HADOOP_OPTS $HADOOP_CLIENT_OPTS"
elif [ "$COMMAND" = "jar" ] ; then
  CLASS=org.apache.hadoop.util.RunJar
  HADOOP_OPTS="$HADOOP_OPTS $HADOOP_CLIENT_OPTS"
elif [ "$COMMAND" = "distcp" ] ; then
  CLASS=org.apache.hadoop.tools.DistCp
  CLASSPATH=${CLASSPATH}:${TOOL_PATH}
  HADOOP_OPTS="$HADOOP_OPTS $HADOOP_CLIENT_OPTS"
elif [ "$COMMAND" = "daemonlog" ] ; then
  CLASS=org.apache.hadoop.log.LogLevel
  HADOOP_OPTS="$HADOOP_OPTS $HADOOP_CLIENT_OPTS"
elif [ "$COMMAND" = "archive" ] ; then
  CLASS=org.apache.hadoop.tools.HadoopArchives
  CLASSPATH=${CLASSPATH}:${TOOL_PATH}
  HADOOP_OPTS="$HADOOP_OPTS $HADOOP_CLIENT_OPTS"
elif [ "$COMMAND" = "sampler" ] ; then
  CLASS=org.apache.hadoop.mapred.lib.InputSampler
  HADOOP_OPTS="$HADOOP_OPTS $HADOOP_CLIENT_OPTS"
else
  CLASS=$COMMAND
fi

 
 
 
ステップ6、jsvc、java実行コマンド
 
 
  exec "$HADOOP_HOME/libexec/jsvc.${JSVC_ARCH}" -Dproc_$COMMAND -outfile "$HADOOP_LOG_DIR/jsvc.out" \
                                                -errfile "$HADOOP_LOG_DIR/jsvc.err" \
                                                -pidfile "$HADOOP_SECURE_DN_PID" \
                                                -nodetach \
                                                -user "$HADOOP_SECURE_DN_USER" \
                                                -cp "$CLASSPATH" \
                                                $JAVA_HEAP_MAX $HADOOP_OPTS \
  
  echo COMMAND=$COMMAND  
  echo HADOOP_OPTS=$HADOOP_OPTS 
  echo CLASS=$CLASS 
  exec "$JAVA" -Dproc_$COMMAND $JAVA_HEAP_MAX $HADOOP_OPTS -classpath "$CLASSPATH" $CLASS "$@"
fi