linux kill进程和子进程小trick

26 篇文章 0 订阅
1 篇文章 0 订阅
       我们的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子进程 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值