张子阳的博客

首页 读书 技术 店铺 关于
张子阳的博客 首页 读书 技术 关于

Spark 问题解决:no org.apache.spark.deploy.master.Master to stop

2018-09-25 张子阳 分类: 大数据处理

今天更新了配置,想要重启一下集群,在执行stop-all.sh脚本时,出现了这样的提示:no org.apache.spark.deploy.master.Master to stop,意思是当前没有运行spark进程。

# $SPARK_HOME/sbin/stop-all.sh
hadoop02: no org.apache.spark.deploy.worker.Worker to stop
hadoop04: no org.apache.spark.deploy.worker.Worker to stop
hadoop03: no org.apache.spark.deploy.worker.Worker to stop
no org.apache.spark.deploy.master.Master to stop

这就奇怪了,当我运行jps查看时,发现Master和Worker进程都是存在的。

# jps
12964 NameNode
3419 ResourceManager
3723 Master
2443 JobHistoryServer
13036 SecondaryNameNode
2189 Jps

如果在master机器上,再次执行start-master.sh脚本,然后用jps查看,会看见居然运行了两个Master进程,其PID不同。

# jps
12964 NameNode
3723 Master
3419 ResourceManager
25200 Master
4334 Jps

于是,查看一下start-master.sh脚本,发现其执行的是spark-daemon.sh这个脚本。

再次打开spark-daemon.sh,发现其顶部有一段说明,包含了所用到的环境变量,其中包括 SPARK_PID_DIR:

# 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 be rsync'd from
#   SPARK_PID_DIR   The pid files are stored. /tmp by default.
#   SPARK_IDENT_STRING   A string representing this instance of spark. $USER by default
#   SPARK_NICENESS The scheduling priority for daemons. Defaults to 0.
#   SPARK_NO_DAEMONIZE   If set, will run the proposed command in the foreground. It will not output a PID file.
##

SPARK_PID_DIR 文件夹的默认是/tmp。而linux系统默认会定期清理/tmp文件夹,删除超时的旧文件,所以,在执行stop-all.sh时,就找不到进程id了。接下来可以在spark-daemon.sh中看一下pid的规则:

pid="$SPARK_PID_DIR/spark-$SPARK_IDENT_STRING-$command-$instance.pid"

如果不清楚这个规则的含义,最好的办法就是再执行一遍 start-master.sh和start-worker.sh,然后看/tmp下生成的文件名:

# $SPARK_HOME/sbin/start-master.sh
# $SPARK_HOME/sbin/start-slave.sh spark://hadoop01:7077
# ls /tmp 
spark-root-org.apache.spark.deploy.master.Master-1.pid
spark-root-org.apache.spark.deploy.worker.Worker-1.pid

如果cat一下这个文件内容,并对比jps下的输出,会看到pid是一致的。

接下来,解决这个问题就比较容易了,我们先要修改环境变量,将$SPARK_PID_DIR设置为常规文件夹,比如/opt/pids。

# mkdir /opt/pids
# vim $SPARK_HOME/conf/spark-env.sh

export SPARK_PID_DIR=/opt/pids

然后,要为当前因为缺少pid文件而无法停止的进程手动创建一个pid文件,并使其内容和jps输出的pid相同。

echo 3723 > /tmp/spark-root-org.apache.spark.deploy.master.Master-1.pid

接下来,再次执行 $SPARK_HOME/sbin/stop-master.sh,就一切正常了,并且以后也不会再出现相同的问题。

如果有多台机器,则通过scp将配置复制到集群中的所有机器上,然后重复上面手工创建id的过程,再重新启动集群即可:

for i in {1..4}; do
scp -P 60034 -r $SPARK_HOME/conf/* hadoop0${i}:$SPARK_HOME/conf
done

然而,这个pid的问题,不仅存在于Spark,YARN、HDFS和Job History Server都有。需要修改 $HADOOP_HOME/etc/hadoop/hadoop-env.sh、$HADOOP_HOME/etc/hadoop/yarn-env.sh、$HADOOP_HOME/etc/hadoop/mapred-env.sh 这三个文件:

# vim $HADOOP_HOME/etc/hadoop/hadoop-env.sh
export HADOOP_PID_DIR=/opt/pids

# vim $HADOOP_HOME/etc/hadoop/yarn-env.sh
export YARN_PID_DIR=/opt/pids

# vim $HADOOP_HOME/etc/hadoop/mapred-env.sh
export HADOOP_MAPRED_PID_DIR=/opt/pids

这三个pid的规则和实例分别如下所示:

pid=$YARN_PID_DIR/yarn-$YARN_IDENT_STRING-$command.pid
# yarn-root-resourcemanager.pid
# yarn-root-nodemanager.pid

pid=$HADOOP_PID_DIR/hadoop-$HADOOP_IDENT_STRING-$command.pid
# hadoop-root-namenode.pid
# hadoop-root-secondarynamenode.pid
# hadoop-root-datanode.pid

pid=$HADOOP_MAPRED_PID_DIR/mapred-$HADOOP_MAPRED_IDENT_STRING-$command.pid
# mapred-root-historyserver.pid

至于修复pid文件的过程,和Spark的完全一样,就不再重复了。

感谢阅读,希望这篇文章能给你带来帮助!