• 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子进程 

  • 相关阅读:
    android 如何引用jar包
    ExoPlayer + 边缓存边播放
    adb打开系统设置的命令
    android 8.0 适配(总结)
    android 7.0适配(总结)
    android 6.0适配(总结)
    常用adb命令
    nginx 简介
    Marshmallow 的用法
    python 自动生成当前项目的requirements文件
  • 原文地址:https://www.cnblogs.com/james1207/p/3303937.html
Copyright © 2020-2023  润新知