今天想停止spark集群,發現執行stop-all.sh的時候spark的相關進程都無法停止。提示:
no org.apache.spark.deploy.master.Master to stop
no org.apache.spark.deploy.worker.Worker to stop
上網查了一些資料,再翻看了一下stop-all.sh,stop-master.sh,stop-slaves.sh,spark-daemon.sh,spark-daemons.sh等腳本,發現很有可能是由於$SPARK_PID_DIR的一個環境變量導致。
我搭建的是Hadoop2.6.0+Spark1.1.0+Yarn的集群。Spark、Hadoop和Yarn的停止,都是通過一些xxx.pid文件來操作的。以spark的stop-master為例,其中停止語句如下:
再查看spark-daemon.sh中的操作:
$SPARK_PID_DIR中存放的pid文件中,就是要停止進程的pid。其中$SPARK_PID_DIR默認是在系統的/tmp目錄:
系統每隔一段時間就會清除/tmp目錄下的內容。到/tmp下查看一下,果然沒有相關進程的pid文件了。這才導致了stop-all.sh無法停止集群。
擔心使用kill強制停止spark相關進程會破壞集群,因此考慮回復/tmp下的pid文件,再使用stop-all.sh來停止集群。
分析spark-daemon.sh腳本,看到pid文件命名規則如下:
pid=$SPARK_PID_DIR/spark-$SPARK_IDENT_STRING-$command-$instance.pid
其中
$SPARK_PID_DIR是/tmp
$SPARK_IDENT_STRING是登錄用戶$USER,我的集群中用戶名是cdahdp
$command是調用spark-daemon.sh時的參數,有兩個:
org.apache.spark.deploy.master.Master
org.apache.spark.deploy.worker.Worker
$instance也是調用spark-daemon.sh時的參數,我的集群中是1
因此pid文件名如下:
/tmp/spark-cdahdp-org.apache.spark.deploy.master.Master-1.pid
/tmp/spark-cdahdp-org.apache.spark.deploy.worker.Worker-1.pid
通過jps查看相關進程的pid:
將pid保存到對應的pid文件即可。
之后調用spark的stop-all.sh,即可正常停止spark集群。
停止hadoop和yarn集群時,調用stop-all.sh,也會出現這個現象。其中NameNode,SecondaryNameNode,DataNode,NodeManager,ResourceManager等就是hadoop和yarn的相關進程,stop時由於找不到pid導致無法停止。分析方法同spark,對應pid文件名不同而已。
Hadoop的pid命名規則:
pid=$HADOOP_PID_DIR/hadoop-$HADOOP_IDENT_STRING-$command.pid
pid文件名:
/tmp/hadoop-cdahdp-namenode.pid
/tmp/hadoop-cdahdp-secondarynamenode.pid
/tmp/hadoop-cdahdp-datanode.pid
Yarn的pid命名規則:
pid=$YARN_PID_DIR/yarn-$YANR_IDENT_STRING-$command.pid
pid文件名:
/tmp/yarn-cdahdp-resourcemanager.pid
/tmp/yarn-cdahdp-nodemanager.pid
恢復這些pid文件即可使用stop-all.sh停止hadoop和yarn進程。
要根治這個問題,只需要在集群所有節點都設置$SPARK_PID_DIR, $HADOOP_PID_DIR和$YARN_PID_DIR即可。
修改hadoop-env.sh,增加:
export HADOOP_PID_DIR=/home/ap/cdahdp/app/pids
修改yarn-env.sh,增加:
export YARN_PID_DIR=/home/ap/cdahdp/app/pids
修改spark-env.sh,增加:
export SPARK_PID_DIR=/home/ap/cdahdp/app/pids
啟動集群以后,查看/home/ap/cdahdp/app/pids目錄,如下: