c/fe

http://d.hatena.ne.jp/uzulla から移行しました。

Topしか使えないサーバーとかありえないけど調査

VPSサーバーにおいて、サーバーの負荷の調査などをおこなった。
定番のコマンドとしてはvmstat top とか、MRTGとかを駆使する訳だが、そのサーバーはVPSだからか殆どのコマンドがつかえず、topコマンドしかつかえなかった。VPSなのにね。

とりあえずデータを集める

sv /root> cat toplog.sh
#!/bin/sh
/bin/echo ---- >> /root/toplog.log
/bin/date >> /root/toplog.log
/usr/bin/top -n 999 >> /root/toplog.log

sv /root> crontab -l
* * * * * /root/toplog.sh >> /root/toplog.sh.log

とかを用意する。

1分毎に出力するので,結構容量を食うが、1ヶ月で200Mbyte程度かしら。(勿論サーバープロセス数によっても変わるが)

出来たデータはこんなの

      • -

Tue Dec 9 23:07:00 JST 2008
last pid: 20734; load averages: 0.42, 0.38, 0.33 up 210+20:56:12 23:07:00
60 processes: 1 running, 59 sleeping

Mem: 2364M Active, 902M Inact, 287M Wired, 177M Cache, 199M Buf, 39M Free
Swap: 8192M Total, 796M Used, 7396M Free, 9% Inuse


PID USERNAME PRI NICE SIZE RES STATE C TIME WCPU CPU COMMAND
13170 www 2 0 14436K 8144K sbwait 0 0:02 1.27% 1.27% httpsd
6204 mysql 18 11 65480K 6468K pause 0 79:23 0.00% 0.00% mysqld
6181 mysql 2 14 65480K 6468K select 1 76:10 0.00% 0.00% mysqld
6182 mysql 2 14 65480K 6468K select 0 54:22 0.00% 0.00% mysqld
5678 mysql 2 11 65480K 6468K poll 0 23:37 0.00% 0.00% mysqld
5497 mysql 2 11 65480K 6468K select 1 17:39 0.00% 0.00% mysqld
1689 root 2 0 4216K 1068K select 0 16:49 0.00% 0.00% sendmai
1153 root 2 0 932K 364K select 0 4:40 0.00% 0.00% syslogd
1461 root 2 0 1080K 572K select 1 4:26 0.00% 0.00% inetd
68856 www 2 0 22788K 16740K sbwait 1 1:13 0.00% 0.00% httpsd
1499 root 10 0 980K 576K nanslp 1 0:52 0.00% 0.00% cron
26311 www 2 0 18924K 12808K sbwait 1 0:44 0.00% 0.00% httpsd
87631 www 2 0 23084K 16972K sbwait 1 0:36 0.00% 0.00% httpsd
32792 www 2 0 22776K 16628K sbwait 1 0:27 0.00% 0.00% httpsd
27749 www 2 0 22780K 16648K sbwait 1 0:26 0.00% 0.00% httpsd

さて、とりあえずプロセス数の分布を集計してみたい。

こういったベタデータを集計するには

cat toplog|grep process|perl -lane 'print $F[0]'|sort -nr |uniq -c|less

などとすると良い。
perl -lane ~
のあたりは、awkとかでやるのが定番だが、俺はPerlで全部やる人なのでこれで。

集計結果を見てみる

すると、こんなデータが得られる

(結構省略してますが)
1 213
1 179
1 168
2 135
2 133
1 121
2 120
8 113
8 109
10 108
11 104
10 103
10 102
15 101
12 99
17 98
21 92
14 91
24 90
21 89
42 83
33 82
50 81
57 74
94 73
104 72
94 71
130 70
139 69
178 68
159 67
218 66
245 65
272 64
287 63
506 59
527 58
608 57
671 56
760 55
883 54
915 53
1068 52
1164 51
1182 50
1373 49
1399 48
1433 47
1596 46
1506 45
1733 44
1750 43
1862 42
2076 41
3372 40
5052 39
177 38
5 37

ふむ、大体40〜50プロセスくらいが常時うごいてそうですね。
気になるのが、213とか、そういうすごいピークがある事です。
こいつはなんだ。

詳しく調べる

生ログをlessって、/213とかで問題のTOPを見てみます。
lessはすばらしいですね、数百メガのファイルでもサクサク開きます。
一瞬で固まるEditorにはできない芸当です(秀丸だけは、こういう用途にも使えるけど)

どうやら今回はApacheがやたら大量に湧いていました、こいつか。

その日付をチェックして(そのために日付をログに出してます)、Apacheのログとつきあわせるとどんなアクセスがあり、どんなプログラムが問題をひきおこしているのかがわかります

同様の方法で、Loadとかも調べられます。

grep process|perl -lane 'print $F[0]'

このあたりを書き換えれば、Loadとかも調べられますね。
$F[何番目のフィールド]という事です。(当然0から)
区切り文字はデフォルトでスペースですが、指定も勿論出来ます。

grep process|perl -F, -lane 'print $F[0]'

とかすると、CSVファイルが扱えます

もうちょっとPerlで色々やれば、それぞれのプログラムのメモリ消費量の推移とか、プロセス数の遷移とか、メモリの消費量とかもばっちり解析ができます。

ログはできるだけ大きく採る

個人的な趣味かもしれませんが、ロガーの時点でそれぞれのフィールドの値をきっちりきりわけて出すのは趣味じゃありません。
とにかくでっかくとって、後でPerlとかを駆使してうまいこと集計するのがよいでしょう。


特に1ヶ月とか、長いスパンじゃないと動静は確認できないので、「あーアレ取り忘れた!」という事がないようなデータ収集方法がほしいですね。

改善点

Cronつかってるので、1分が最大の分解能です。
常時実行プロセスつくってもいいけど、それが死んだら困るのでね。

今回はサーバーの問題でVmstatとか、Mrtgとかつかえませんでしたが、そっちはそっちで是非取得すべきです。
Mrtgまで入れるのが面倒なら、ifconfigの出力のパケット数を取得しておけば後でどうとでもなります。

つーかぶっちゃけ

今回のようなことはVmstatだけでも大体どうにかなりますね、

perl -lane 'print $F[0]'|sort -nr |uniq -c

ってのを書きたかっただけですね、はいw