承接上面“spark-core_05: $SPARK_HOME/sbin/start-all.sh、start-master.sh脚本分析”
#!/usr/bin/envbash
#Runs a Spark command as a daemon. 将Spark命令作为守护进程运行。
#
#Environment Variables
#
# SPARK_CONF_DIR Alternate conf dir. Default is${SPARK_HOME}/conf.
# SPARK_LOG_DIR Where log files are stored.${SPARK_HOME}/logs by default.
# SPARK_MASTER host:path where spark code should bersync'd from
# SPARK_PID_DIR The pid files are stored. /tmp by default.
# SPARK_IDENT_STRING A string representing this instance ofspark. $USER by default
# SPARK_NICENESS The scheduling priority fordaemons. Defaults to 0.
# 环境变量:
# SPARK_PID_DIR的值是/tmp,
# SPARK_IDENT_STRING表示这个spark实例的字符串,默认是当前使用用户名:$USER
# SPARK_NICENESS 守护进程的调度优先级。 默认为0
##
# 从start-master.sh调用过来的:spark-daemon.sh start org.apache.spark.deploy.master.Master 1 luyl152 --port 7077 --webui-port 8080
# 其中Master后面的1表示spark实例的数量
# 从start-slave.sh调用过来的: spark-daemon.sh start org.apache.spark.deploy.worker.Worker 1--webui-port 8081 spark://luyl152:7077
usage="Usage:spark-daemon.sh [--config <conf-dir>] (start|stop|submit|status)<spark-command> <spark-instance-number> <args...>"
# if no args specified, show usage, 如果没有参数,就直接退出
if [$# -le 1 ]; then
echo $usage
exit 1
fi
if [-z "${SPARK_HOME}" ]; then
export SPARK_HOME="$(cd "`dirname"$0"`"/..; pwd)"
fi
#这个spark-config.sh作用就是将$SPARK_CONF_DIR环境变量的值取出来.即:${SPARK_HOME}/conf
."${SPARK_HOME}/sbin/spark-config.sh"
#get arguments
# Check if --config is passed as an argument. It is an optionalparameter.
# Exit if the argument is not a directory.
#如果传进来的 --config,则后面需要跟config的目录,如果传了这个--config,没有指定目录并且目录不存在,则会退出
if ["$1" == "--config" ]
then
#如果发现第一个参数是“--config” 则使用shift将下个参数变成第一个参数
shift
conf_dir="$1"
if [ ! -d "$conf_dir" ]
then
echo "ERROR : $conf_dir is not adirectory"
echo $usage
exit 1
else
export SPARK_CONF_DIR="$conf_dir"
fi
shift
fi
#在start-master.sh时,下面的环境变量的值如下:
#这个option变量就是start,可以(start|stop|submit|status)
#command就是org.apache.spark.deploy.master.Master
#instance就是1
option=$1
shift
command=$1
shift
instance=$1
shift
spark_rotate_log()
{
# $1是log的目录:${SPARK_HOME}/logs/spark-root-org.apache.spark.deploy.master.Master-1-luyl152.out
log=$1;
num=5;
#run_command 调用这个函数只传了一个参数
if [ -n "$2" ]; then
num=$2
fi
if [ -f "$log" ]; then # rotatelogs
while [ $num -gt 1 ]; do
#将num-1赋给prev,并判断文件是否存在,如果存在将它们循环删除掉
prev=`expr $num - 1`
[-f "$log.$prev" ] && mv "$log.$prev""$log.$num"
num=$prev
done
mv "$log" "$log.$num";
fi
}
#该脚本会加载spark-env.sh加载一次。并设置环境变量SPARK_SCALA_VERSION=2.10及SPARK_ENV_LOADED=1
. "${SPARK_HOME}/bin/load-spark-env.sh"
#如果$SPARK_IDENT_STRING为空串则将当前登入用户$user给它。
if ["$SPARK_IDENT_STRING" = "" ]; then
export SPARK_IDENT_STRING="$USER"
fi
#这个环境变量用于在launcher.Main中可以打印CMD相关的命令,
#在launcher.Main这个变量可以是任何值,只要不为空就可以
exportSPARK_PRINT_LAUNCH_COMMAND="1"
# get log directory 如果变量SPARK_LOG_DIR为空则将${SPARK_HOME}/logs给它
if ["$SPARK_LOG_DIR" = "" ]; then
exportSPARK_LOG_DIR="${SPARK_HOME}/logs"
fi
#创建这个目录
mkdir-p "$SPARK_LOG_DIR"
#在${SPARK_HOME}/logs目录下面创建一个隐藏文本.spark_test
touch"$SPARK_LOG_DIR"/.spark_test > /dev/null 2>&1
#判断touch命令是否执行成功,如果成功将隐藏文本.spark_test删除,
#否则使用当前用户给${SPARK_HOME}/logs修改文件权限
TEST_LOG_DIR=$?
if ["${TEST_LOG_DIR}" = "0" ]; then
rm -f "$SPARK_LOG_DIR"/.spark_test
else
chown "$SPARK_IDENT_STRING" "$SPARK_LOG_DIR"
fi
#SPARK_PID_DIR变量串为空,则将/tmp赋给它
if ["$SPARK_PID_DIR" = "" ]; then
SPARK_PID_DIR=/tmp
fi
#some variables
#log变量值:${SPARK_HOME}/logs/spark-root-org.apache.spark.deploy.master.Master-1-luyl152.out
#pid变量值:${SPARK_HOME}/logs/spark-root-org.apache.spark.deploy.master.Master-1.pid
log="$SPARK_LOG_DIR/spark-$SPARK_IDENT_STRING-$command-$instance-$HOSTNAME.out"
pid="$SPARK_PID_DIR/spark-$SPARK_IDENT_STRING-$command-$instance.pid"
# Set default scheduling priority.设置调度优先级,将SPARK_NICENESS变量值为0
if ["$SPARK_NICENESS" = "" ]; then
export SPARK_NICENESS=0
fi
#当$option值是start和submit会执行run_command函数
#run_command参数是由下面代码传进来的: class luyl152 --port 7077--webui-port 8080
#如果是start-slava.sh 则变成:class --webui-port8081 spark://luyl152:7077
run_command(){
mode="$1"
shift
#又shift一下,目的是把调用这个方法传进来的class去掉
#将SPARK_PID_DIR=/tmp对应的目录创建出来
mkdir -p "$SPARK_PID_DIR"
#判断pid对应的目录是否存在:${SPARK_HOME}/logs/spark-root-org.apache.spark.deploy.master.Master-1.pid
#如果已经启动了spark,会提供先停止它
if [ -f "$pid" ]; then
TARGET_ID="$(cat"$pid")"
#ps -p 表示pid 进程使用cpu的时间
if [[ $(ps -p "$TARGET_ID" -ocomm=) =~ "java" ]]; then
echo "$command running as process$TARGET_ID. Stop it first."
exit 1
fi
fi
#SPARK_MASTER不为空,同步删除某些文件
if [ "$SPARK_MASTER" !="" ]; then
echo rsync from "$SPARK_MASTER"
rsync -a -e ssh --delete --exclude=.svn--exclude='logs/*' --exclude='contrib/hod/logs/*' "$SPARK_MASTER/""${SPARK_HOME}"
fi
#回滚log日志
spark_rotate_log "$log"
echo "starting $command, logging to$log"
#如果是start-master.sh则当前的$mode是class
case "$mode" in
(class)
#nice -n 表示程序执行的优先级,此时调用就进入$SPARK_HOME/bin/spark-class org.apache.spark.deploy.master.Masterluyl152 --port 7077 --webui-port 8080
#查看“spark-core_02:spark-submit、spark-class脚本分析”
#$! 表示Shell最后运行的后台Process的PID
nohup nice -n "$SPARK_NICENESS""${SPARK_HOME}"/bin/spark-class $command "$@" >>"$log" 2>&1 < /dev/null &
newpid="$!"
;;
(submit)
nohup nice -n "$SPARK_NICENESS""${SPARK_HOME}"/bin/spark-submit --class $command "$@">> "$log" 2>&1 < /dev/null &
newpid="$!"
;;
(*)
echo "unknown mode: $mode"
exit 1
;;
esac
#将新的$newpid值加到$pid的文本中
echo "$newpid" >"$pid"
#休息2秒,估计是等spark的master启动吧,如果新的pid没有
sleep 2
# Check if the process has died; in that casewe'll tail the log so the user can see
#ps -p 表示pid 进程使用cpu的时间 , -o表示用户自定义的格式
if [[ ! $(ps -p "$newpid" -o comm=)=~ "java" ]]; then
echo "failed to launch $command:"
tail -2 "$log" | sed 's/^/ /'
echo "full log in $log"
fi
}
#$option可以是start|stop|submit|status
#start和submit都是执行run_command函数,并且在现有参数后面追加了class 或submit
#参数:start org.apache.spark.deploy.master.Master 1 luyl152 --port 7077--webui-port 8080
#上面shfit之后:luyl152 --port 7077 --webui-port8080
case$option in
(submit)
run_command submit "$@"
;;
(start)
run_command class "$@"
;;
(stop)
if [ -f $pid ]; then
TARGET_ID="$(cat"$pid")"
if [[ $(ps -p "$TARGET_ID" -ocomm=) =~ "java" ]]; then
echo "stopping $command"
kill "$TARGET_ID" &&rm -f "$pid"
else
echo "no $command to stop"
fi
else
echo "no $command to stop"
fi
;;
(status)
if [ -f $pid ]; then
TARGET_ID="$(cat"$pid")"
if [[ $(ps -p "$TARGET_ID" -ocomm=) =~ "java" ]]; then
echo $command is running.
exit 0
else
echo $pid file is present but $commandnot running
exit 1
fi
else
echo $command not running.
exit 2
fi
;;
(*)
echo $usage
exit 1
;;
esac
至此, org.apache.spark.deploy.master.Master就被$SPARK_HOME/bin/spark-class启动起来了,后面章节分析org.apache.spark.deploy.master.Master的源码