リソース監視ツールのmuninは手軽に使えて素晴らしいのだが、監視対象のサーバが増えてくると集計サーバの負荷(主にディスクI/O)が馬鹿にならなくなってくる。そこでこちらのサイトを参考にして、データファイルとHTMLファイルをtmpfs上に移動してみた。
環境
- CentOS 6
- munin-1.4.5 (EPELリポジトリからインストール)
- メモリ: 8GB
データファイルとHTMLファイルの場所は /etc/munin/munin.conf の dbdir と htmldir で変更できる…はずなのだが、プラグインの中には /var/lib/munin のパスを決め打ちにしているものがあるらしく、dbdir を変更するとうまく動かなかった。仕方がないのでHTMLファイルを /var/lib/munin 以下に移動して、tmpfs を /var/lib/munin にマウントすることにした。
まずHTMLファイルを移動する。以下の操作はroot権限で、muninの集計を停止してから行う。
muninの集計を止めるには、munin-cronの実行権限を外すか、/etc/cron.d/munin を編集してcronによる定期実行を止める。
# munin-cronの停止 chmod ugo-x /usr/bin/munin-cron # 念のためmuninプロセスが動いていないか確認しておく ps aux | grep munin
次にHTMLファイルをディレクトリごとコピー、そのパスにあわせてmuninとApacheの設定を変更する。
cp -a /var/www/html/munin/ /var/lib/munin/html vim /etc/munin/munin.conf # htmldir /var/lib/munin/html vim /etc/httpd/conf.d/munin.conf # 私の環境ではcgiディレクトリは /var/www/munin/cgi に移してあるので # ScriptAlias /munin/cgi/ /var/www/munin/cgi/ # Alias /munin/ /var/lib/munin/html/
ここまで終えたら一旦muninの集計を再開し、正しく動くことを確認しておく。確認できたら再び集計を停止して、tmpfsの設定に移る。tmpfsに割り当てる容量だが、とりあえず参考サイトに従って1GBとした。二十数サーバを数年間監視した結果のデータ+HTMLファイルが300MB弱だったので、1GBあれば当分は大丈夫だろう。
vim /etc/fstab #tmpfs /var/lib/munin tmpfs rw,size=1024M 0 0
一旦データを退避してから /var/lib/munin にtmpfsをマウントし、退避しておいたデータを戻す。
mv /var/lib/munin /var/lib/munin.backup mkdir /var/lib/munin mount /var/lib/munin cp -a /var/lib/munin.backup/* /var/lib/munin/
これでmuninが更新するファイルは全てメモリ上に置かれることになった。が、このままだとマシンが再起動されるとデータが消滅してしまうので、バックアップ策を講じる必要がある。参考サイトではcronを使って1時間ごとにバックアップを行っているが、それだと更新中の不完全なデータがバックアップされる危険性がある。そもそもmuninの集計はcronで5分ごとに実行されるのだから、次のような方針でバックアップ/リストアをすることにした。
- 30分に一回、集計の「後に」データをバックアップする
- 毎回、集計の「前に」データの有無をチェックして、なければデータをリストアする。このチェックは単純にファイルの有無を調べるだけなので、5分ごとに実行しても負担にはならない
このためにmunin-cronをラップする次のようなシェルスクリプトを書いた。
#!/bin/sh rsync=/usr/bin/rsync munin_cron=/usr/bin/munin-cron munin_dir=/var/lib/munin backup_dir=/home/munin/backup lock_file=/var/tmp/munin-cron-backup.lock die() { echo $1 exit 1 } lock() { test -e $lock_file && die "Backup/retore process is already runnning" touch $lock_file } unlock() { rm -f $lock_file } backup() { lock || die "Failed to lock the backup process" $rsync -au $munin_dir/ $backup_dir/ unlock } restore() { lock || die "Failed to lock the restore process" if [ ! "(" -e $munin_dir/datafile -a -d $munin_dir/html ")" ]; then $rsync -au $backup_dir/ $munin_dir/ fi unlock } restore test -x $munin_cron && $munin_cron if [ "$1" = "backup" ]; then backup fi
このスクリプトでは datafile というファイルと html ディレクトリの存在をもって、「データが存在する」と判断する。一応、同時実行を避けるための簡易的なロックも付けてみた。5分に一回しか実行されないと分かっているのだから、この程度でも多少は意味があるだろう。各種コマンドやバックアップ先などのパスは好みで変えて欲しい。私はこのシェルスクリプトやバックアップを /home/munin 以下にまとめることにした。
あとはmunin-cronの代わりに、/etc/cron.d/munin の中でこのスクリプトを実行するよう設定する。30分に一回は引数に backup を与えて実行することで、バックアップが作成される。
MAILTO=root 0,30 * * * * munin /home/munin/bin/munin-cron.sh backup 5,10,15,20,25,35,40,45,50,55 * * * * munin /home/munin/bin/munin-cron.sh
リストアは集計前に勝手に行われるので、再起動しても何もしなくていい。
最後に実施前後のCPU使用率のグラフを載せておく。確かにI/O待ちはガクンと減った(ちょっとだけ出ているのはバックアップ)。
それから集計に要する時間も多少は短縮されたようだ。もっともネットワーク経由でクライアントに接続する部分がボトルネックになっているようなので、あまり結果は安定していない。


