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 が妥当な値になっていれば,そんなに悲惨なことにはならないと思います。

以上,ドキュメントを眺めながらつらつらと書いてきましたが,恥ずかしながらプロダクションサーバで使ったことはないので,なにか間違いとかありましたらご指摘頂けるとうれしいです。