Spark 问题解决:no org.apache.spark.deploy.master.Master to stop
今天更新了配置,想要重启一下集群,在执行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的完全一样,就不再重复了。
感谢阅读,希望这篇文章能给你带来帮助!