memcachedの自動再起動スクリプトを書いた

「おかしい」とか「間違ってる」などありましたら、バンバンご教授くださいませm(_ _)m

実装環境

  • CentOS5系
  • memcached 1.4.5
  • nagiosのpluginが入っていることが前提
  • 言語は依存関係が少ないbashを利用

私が管理しているサーバはすべてNagios+nrpeによる監視をしているのでnagiosのpluginが入っています。
もし入っていない場合はtelnetで書き直すなどtcp接続のコマンドを利用してください。

実行するコマンドの出力確認

今回利用するpluginのオプションは以下の通りになります。

# /usr/lib64/nagios/plugins/check_tcp  -H localhost -p 11211 -t 5 -E -s 'stats\r\nquit\r\n' -e 'uptime' 

このコマンドを実行すると下記の出力が得られます。

TCP OK - 0.001 second response time on port 11211 [STAT pid 26729
STAT uptime 2213898
STAT time 1334472012
STAT version 1.4.5
STAT pointer_size 64
STAT rusage_user 6.167062
STAT rusage_system 8.447715
STAT curr_connections 10
STAT total_connections 27880
STAT connection_structures 11
STAT cmd_get 0
STAT cmd_set 0
STAT cmd_flush 0
STAT get_hits 0
STAT get_misses 0
STAT delete_misses 0
STAT delete_hits 0
STAT incr_misses 0
STAT incr_hits 0
STAT decr_misses 0
STAT decr_hits 0
STAT cas_misses 0
STAT cas_hits 0
STAT cas_badval 0
STAT auth_cmds 0
STAT auth_errors 0
STAT bytes_read 195184
STAT bytes_written 22385028
STAT limit_maxbytes 134217728
STAT accepting_conns 1
STAT listen_disabled_num 0
STAT threads 4
STAT conn_yields 0
STAT bytes 0
STAT curr_items 0
STAT total_items 0
STAT evictions 0
STAT reclaimed 0
END]|time=0.000521s;;;0.000000;5.000000

この出力の中から不変的な文字列を抽出し、比較することで異常を検知することが可能です。
今回利用した文字列は”TCP OK”になります。

スクリプトの詳細

1回のチェックで失敗した場合に再起動をかけてしまうと誤検知による再起動がかかってしまう可能性があるので複数回チェックを行います。
自動再起動のスクリプトは以下の通りです。

#!/bin/bash

TCPCHECK_CMD=/usr/lib64/nagios/plugins/check_tcp
CHK_OK="TCP OK"
COUNT=1

while [ $COUNT -le 3 ];
do
RES=`$TCPCHECK_CMD -H localhost -p 11211 -t 5 -E -s 'stats\r\nquit\r\n' -e 'uptime' | awk '{print $1,$2 }' | head -n 1`

if [ "$RES" = "$CHK_OK" ]; then
echo "memcached status OK"
exit 0
else
echo "memcached status NG"
fi
COUNT=`expr $COUNT + 1`
sleep 30

if [ $COUNT -gt 3 ]; then
/etc/rc.d/init.d/memcached restart
echo "RESTART"
fi

done

exit 0

  • 11211のlocalhostをチェック
  • 正常動作した場合はそのチェックしたタイミングでスクリプトから抜ける
  • チェック間隔は30秒空ける
  • COUNTを利用してチェック回数で再起動するかどうか判定を行なっている

実行した時の出力

まずは正常動作している場合にスクリプトを実行します。

# sh memcache_restart.sh 
memcached status OK

次にmemcachedが応答しない場合にスクリプトを実行します

memcachedが応答しない場合を作るためにあえてmemcachedを停止してから実行しました。

# sh memcache_restart.sh 
memcached status NG
memcached status NG
memcached status NG
memcached を停止中: [失敗]
memcached を起動中: [ OK ]
RESTART

再起動されたかをpsコマンドで確認します。

 # ps uaxf |grep memcached
root 21438 0.0 0.1 65460 832 pts/0 S+ 15:57 0:00 \_ grep memcached
root 21150 0.0 0.1 69016 764 ? Ssl 15:57 0:00 memcached -d -p 11211 -u root -m 128 -c 1024 -P /var/run/memcached/memcached.pid

現在時刻でmemcachedが起動していることが確認できました。
正常に再起動されることがわかりましたが、これだといつ再起動がかかったのかわかりにくいのでrestartをかけるところに|を利用して自分のメールアドレスに対してmailコマンドを実行すればいいと思います。
複数サーバに仕込む場合にはどのサーバが再起動されたか確認するために件名にホスト名が入る様にするのもポイントになります。

〜忘れていたので追記〜

実装方法

memcachedの再起動にはroot権限が必要なのでrootのcrontabに登録します。

 # crontab -e
 */5 * * * * /bin/sh /root/memcache_restart.sh > /dev/null 2>&1

これで5分に1回チェックを行なってくれます。時間は適度調整してください。
スクリプトでも30秒のsleepが3回発生するので再起動されるまでに最大6分30秒かかります。