Apache + mod_perl - MaxClients の値に注意
やっちまった……。きっとだれもが通る道。というかとっくに FAQ か。
恥ずかしながら、知らなかったッス。これって mod_ruby でもありうる話だよね?
Apache で mod_perl を使用する時は MaxClients 設定に注意!
- Apache の MaxClients(子プロセスの最大数) デフォルト設定は 150。
- 他のモジュールにも影響されるが、mod_perl 組み込み時、子プロセス1つのメモリサイズが 20〜30MB 程度になる。
- よって、同時接続数 150 までアクセスされると 3G から 4.5G メモリを喰うことになる。
そんなメモリねぇ〜www なので、スワップ・スワップ(SWAP x SWAP と書いてみたがヤな感じだった)。swap もオーバーしちゃったり。
対策:
- MaxClients は「総メモリサイズ / Apache 子プロセス1つのメモリサイズ」(ドンブリ勘定)にする。
- できれば KeepAlive は Off
- 1ページで引っこ抜くリソースが多い(画像が多いとか)場合は、画像だけ「pound + 別のウェブサーバー」に任せる、といった構成にする。
- Off にせずとも MaxKeepAliveRequests, KeepAliveTimeout を調整して改善するかもしれない。
- Apache モジュールを減らして、子プロセスのメモリサイズを減らす
$ ab -c 100 -n 1000 -k http://example.com/hoge
テスト機で試した。MaxClients 調整前はめっさ重くなる(SSHまで!)。MaxClients 調整後はなんとか耐えられる。
総メモリサイズ は /proc/meminfo からわかるとして、1子プロセスのメモリサイズは ps の出力の VSZ で良いのかな?
$ ps auxww | grep ^www USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND www 2783 2.2 2.7 33080 24456 ? S 11:26 0:02 /usr/local/apache/bin/httpd ...
モジュール入れすぎ!もあるけど、VSZ と RSS じゃ大分変わるんだよなぁ。
404 - エラー: 404
わかったような、わからんような説明だな(←わかってない)。
あと、スライドにある Apache の Shared_RAM_per_Child (子プロセスの共有メモリ量)ってどうやってわかるんだろ? むー。
追記:
はてなブックマークの naoya さんのコメントによると、
Shared RAM per Child は RSS - SHARE. 正確に知りたければ GTop を使うと良いです。
とのこと。リモート親切だぁね。
kounoike さんのトラックバックによると、linux カーネル 2.6.11.7 以降は /proc/プロセスID/smaps でわかるらしい。
御二方サンクス!
コメントしてくれた id:lyokato さんもサンクス!
追記2:
WebプログラマのためのCopy On Write解説:mod_perl/FastCGIでメモリを節約する方法 | Typemiss.net
linux では fork(2) の Copy on Write 機能のおかげで、高速 fork&効率的なメモリ共有ができているんだって。"Copy on Write" は「(差異が生じる時の)書き込み時に初めてコピーされる」機能ってとこか。
モジュールも複製されていくのかぁ。勉強になった。