LoginSignup
1
0

More than 1 year has passed since last update.

ゾンビ化した親プロセスをすべてのノードから一掃したい

Last updated at Posted at 2022-06-14

状況

japanクラスターにjapan{01..10}.jpy.netという名の10つのノードが存在するとする。
mpd.pyというプログラムが正常終了せずに実行可能状態のまま残ってしまうとき、演算能力が著しく低下することがわかった。
そのため、以下のスクリプトを定期実行することで解決した。

コード

  #!/bin/sh
 
  NAME=`hostname`
  HOST=`echo $NAME|rev|cut -c 11-|rev`
  echo "## hostname ##"
  echo $HOST
  echo " "
  NODES=(`cat /etc/hosts|grep $HOST|awk '{print $2}'|rev|cut -c 9-|rev|grep $HOST`)
  
  echo "Kill mpd.py !!!"
  for j in ${NODES[@]}
  do
  echo " "
  echo " "
  echo "##   $j   ##"
  cnt=`/usr/bin/rsh $j ps aux --sort start_time |grep mpd.py|wc -l`
  echo "jobcount  $cnt"
  
  cpucnt=`/usr/bin/rsh $j grep processor /proc/cpuinfo | wc -l`
  echo "nodecpus $cpucnt"
  
  jobremain=`expr $cpucnt + $cpucnt`
  echo "jobremain count $jobremain"
  
  jobkillcnt=`expr $cnt - $jobremain`
  echo "killjob count $jobkillcnt"
  
  if [ $jobkillcnt -le 0 ]; then
    echo "no remaining processes"
    continue
  fi  
  
  killjoblist=(`/usr/bin/rsh $j ps aux --sort start_time|grep mpd.py|awk '{print $2}'|head -n $jobkillcnt`)
  flag=(`/usr/bin/rsh $j ps auxf --sort start_time|grep mpd.py|grep -v grep|head -n $jobkillcnt|fgrep "\_"`)

  if [ -n "$flag" ]; then
    echo "Exist child processes"
    continue
  fi  

  killcnt2=`expr $jobkillcnt + 1`
  flag2=(`/usr/bin/rsh $j ps auxf --sort start_time|grep mpd.py|grep -v grep|head -n $killcnt2|tail -n 1|fgrep "\_"`)

  if [ -n "$flag2" ]; then
    echo "Exist child processes"
    continue
  fi  

  for i in "${killjoblist[@]}"
  do  
    chk=`/usr/bin/rsh $j ps aux|grep mpd.py |grep $i`
    if [ -z "$chk" ]; then
      continue
    fi  
    /usr/bin/rsh $j kill $i
  done
  wait
  #TCPポート枯渇対策
  sleep 1m
done

コード解説

例外処理

 killjoblist=(`/usr/bin/rsh $j ps aux --sort start_time|grep mpd.py|awk '{print $2}'|head -n $jobkillcnt`)
 
 flag=(`/usr/bin/rsh $j ps auxf --sort start_time|grep mpd.py|grep -v grep|head -n $jobkillcnt|fgrep "\_"`)

killjoblistはその名の通りkillする予定のPID配列です。flagは例外処理で消すリストの中に子プロセスが存在したらskipするようにしてあります。flag2は消すリストの最後尾が親プロセスで子が隠れているコーナーケースを考えた処理です。

TCPポート枯渇対策

 slepp 1m

これをつけないとAll port usedみたいなエラーを吐いて異常終了します。1mの意味はCentOSではデフォルトのTCPのタイムアウト時間が1mだからです。

xargsを使ってkillするほうが楽かもしれないけど、rootでkillコマンドをスクリプトで実行する危険性を考えると、本当に消してもよいか丁寧にチェックしたいので用いませんでした。その他もっと良い書き方がありましたらコメントで教えてください。

定期実行したい

rootのcrontabに以下を追記してやればよい。日曜日と木曜日の午前0時に実行する設定

0 0 * * 0,4 /usr/local/bin/mpdestroy 2>> /var/log/mpdestory_log/log_mpdestory_error_$(date +\%Y\%m\%d).log
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0