歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux基礎 >> 關於Linux

linux kill進程和子進程小trick

我們的hive web是調用polestar restful service(https://github.com/lalaguozhe/polestar-1)來執行具體的hive或者shark語句的,這幾天有用戶說hive web上的kill按鈕失效了,雖然已經顯示停止了查詢,但是其實提交到jobtracker的mapred job或者spark worker節點上作業還在running。我看了下,確實有這個問題。

polestar對於每一條query執行的命令如下

sudo -u yukang.chen bash -c "echo \$\$ > /tmp/hive.pid;source /etc/profile;export KRB5CCNAME=/tmp/krb5cc_500;hive -e 'select count(1) from hippolog'"

先sudo成提交query的用戶,將用戶bash -c進程號輸出到一個文件下,設置好環境變量,再起一個java子進程執行語句

ps: 輸出進程號到一個文件下是為了之後要kill作業用,這邊由於$符號在雙引號裡面,所以會被替換成當前用戶的bash進程號,而我們需要獲取的是sudo成指定用戶執行命令的進程號,所以要對$符號加上反斜槓來轉義

yukang.chen用戶終端看ps xuf

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND  
1158     30497  0.0  0.0 106204  1556 pts/25   S+   15:08   0:00 bash -c echo $$ > /tmp/hive.pid;source /etc/profile;export KRB5CCNAME=/tmp/krb5cc_500;hive -e 'select count(1) from hippolog'  
1158     30504 29.5  2.2 9644528 178476 pts/25 Sl+  15:08   0:28  \_ /usr/local/jdk/bin/java -Dproc_jar -Xmx7000m -server -XX:ParallelGCThreads=8 -XX:+UseConcMarkSweepGC -Dhadoop.log.dir=/data/logs

java進程的PPID就是bash -c的進程號30497(也是/tmp/hive.pid的值),構成父子進程關系

用戶前端按下kill按鈕後,後端會sudo成指定用戶,先讀取pid文件,再kill -9 pid

觀察發現父進程是被kill掉了,但是子進程還活著,而且PPID已經換成為1,也就是init(1)進程

查看命令ps -p 30504 -l

F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD  
0 S  1158 30504     1 16  80   0 - 2411132 futex_ pts/25 00:00:28 java

這種kill方式導致了雖然kill了父進程,但是真正執行hive和shark的java進程還活著,沒有退出

解決方式有兩種:

1. 使用kill -- -<PPID>

這種方式執行語句不變, 更改kill命令,PPID前是一個負號,這樣會將以PPID為首的整個進程樹(包括子進程)都kill掉

2. 使用exec命令

這種方式需要更執行語句,在hive命令前加上exec

exec命令會將子進程替換當前進程執行(bash -c 替換成hive java進程),如果hive之後還有後續命令都不會執行.

執行語句如下:

sudo -u yukang.chen bash -c "echo \$\$ > /tmp/hive.pid;source /etc/profile;export B5CCNAME=/tmp/krb5cc_500;exec hive -e 'select count(1) from hippolog'"
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND  
1158     32068 59.0  3.6 9577964 290476 pts/25 Sl+  15:18   0:28 /usr/local/jdk/bin/java -Dproc_jar -Xmx7000m -server -XX:ParallelGCThreads=8 -XX:+UseConcMarkSweepGC -Dhadoop.log.dir=/data/logs -Dh

因為child java process替換了parent bash -c process,所以看到的只有一個java process,這樣我們kill的話,就很容易了,不需要kill子進程

 

Copyright © Linux教程網 All Rights Reserved