Apache prefork MPM のプロセス数
mod_perl 環境での最適な設定を探るべく,prefork MPM(すなわち古典的 Apache)について調べてみました。実地テストをしたわけではなく,あくまでドキュメントに基づくシミュレーションです。
まず,prefork MPM では ServerLimit ディレクティブはあまり意味を持ちません(MaxClients 以上の値にしておけば OK)ので省略します。
MaxClients = 8 StartServers = 4 MinSpareServers = 2 MaxSpareServers = 6 MaxRequestsPerChild > 0
という設定でのシナリオを考えてみました。
コネクション | 動作 | |
---|---|---|
1. | ........ | httpd 起動したよ |
2. | ----.... | StartServers = 4 だから4つフォークするよ |
3. | C---.... | 1人からリクエストがきたよ |
4. | ----.... | コネクション閉じたよ |
5. | CCC-.... | 3人からリクエストがきたよ |
6. | ccc--... | MinSpareServers = 2 に満たないから1つフォークするよ |
7. | cccCCC.. | さらに3人からリクエストがきたよ |
8. | cccccc-- | MinSpareServers = 2 に満たないから2つフォークするよ |
9. | ccccccCC | さらに3人からリクエストがきたよ; 3人目はちょっと待っててね |
10. | C------- | 8人がコネクション閉じたよ; 先ほどの方どうぞ |
11. | c------. | MaxSpareServers = 6 を超えてたから1つ殺したよ |
以上から,
- StartServers は割とどうでもいい
- 同時接続数が激しく増減するサイトでは MinSpareServers をチューニングしたほうがよい(たとえば,上記 7. での 3 人目は 1, 2 人目よりほんの少しだが待たされる)
ことがわかります。
このままだと,ある程度「もまれた」後のサーバには最低でも MaxSpareServers のプロセスが居残りそうですが,MaxRequestsPerChild > 0 の場合,設定されたリクエストを処理したプロセスが消滅していくので,同時接続数が少ない状況では,いつか MinSpareServers の数までおちていくことでしょう。
さて,mod_perl 環境での設定ですが。
まず,Fedora のデフォルトでは MaxClients は 256 となっています。ですが,mod_perl の場合,一つのプロセスあたりのメモリ使用量が多くなるので,本気で 256 同時接続が起きた場合,たいていの環境ではメモリ不足→スワップ→スラッシングが発生すると考えられます。もう少し小さい値を設定しましょう(参考)。
次に,MaxRequestsPerChild ですが,あまり小さい値を指定するとプロセスの再生成が増えるので,コンパイルされたモジュールを再利用するという mod_perl のうまみが減ってしまいます。逆に大きな値に設定した場合,メモリリークのあるプログラムや,富豪的にハッシュ等をキャッシュしているプログラムにより,プロセスの使用メモリがどんどん増えてしまいます。やはり Fedora のデフォルト値 4000 は多い気がします。実際に使っているプログラムのメモリ使用量の変化をトラックし,チューニングしたほうがよいでしょう。少なくとも 0 に指定するのはやめましょう。
MinSpareServers や MaxSpareServers については,上にあげたことを参考に,同時接続数の変移を考慮してチューニングしましょう。MaxClients が妥当な値になっていれば,そんなに悲惨なことにはならないと思います。
以上,ドキュメントを眺めながらつらつらと書いてきましたが,恥ずかしながらプロダクションサーバで使ったことはないので,なにか間違いとかありましたらご指摘頂けるとうれしいです。