TIS株式会社の小林です。今回はApache HTTP Server(Apache)の設定についてお話しします。
NetCommonsやSugarCRMなどスクリプト系言語で実装されたビジネスアプリケーションをApacheで動作させる場合、mod_perl、mod_phpなどApacheの追加モジュールで動作させることが良くありますが、この時のApacheの1プロセスの使用メモリは100MBを超える場合も少なくありません。
もしmod_perlやmod_phpなどを利用して、かつApacheをデフォルト設定で動かしているならば、アクセス数が多くなった時にメモリが足りなくなり、スワップが頻発して急激な性能劣化を引き起こしたり、最悪の場合OOM-Killerが動作して他のプロセスにまで影響を与える可能性があります。そのようなトラブルを未然に防ぐためにApacheの設定を見直しましょう。
ここで紹介する情報はCentOS 6.2、Apache 2.2.15(preforkで動作)に対するものです。他のOSや違うバージョンのApacheや違うMPMに関しても同じ考え方を適用可能ですが、今回は割愛させていただきます。
設定見直しに必要な情報は以下の通りです。
- ビジネスアプリケーションを動作させた状態でのApacheの子プロセスあたりの平均メモリ使用量
 
 【Apacheに割り当て可能なメモリ量】サーバの総メモリ量から、OSのメモリ使用量、キャッシュ・バッファのメモリ使用量、Apache以外に動作させているデータベースなどのプロセスのメモリ使用量を引いたものがApacheに割り当て可能なメモリ使用量です。Linuxであればfreeコマンド実行で簡単にわかります。OSの起動直後にfreeコマンドの実行した例を以下に示します。
# free
                              total         used               free         shared     buffers      cached
Mem:                          2054984      293068       1761916           0           7528     68328
-/+ buffers/cache:  217212       1837772
Swap:                         2064376           0                 2064376
これらの数値の単位はKB(キロバイト)です。Apacheに割り当て可能な最大メモリ量は-/+ buffers/cache:行のfree列です。この値はキャッシュ・バッファが使っているメモリも利用可能なメモリとして含めています。キャッシュ・バッファはIOの高速化に寄与しますのである程度の大きさを見込む必要があります。そのため、あまりぎりぎりまでApacheにメモリを与えすぎないようにしましょう。また同じサーバでデータベースなどを動作させる場合にはそのプロセスのメモリ使用量も見込む必要があります。
【ビジネスアプリケーションを動作させた状態でのApacheの子プロセスあたりの平均メモリ使用量】実際に稼働しているApacheプロセスのメモリ量を調べます。今回はPreforkで動作させるので、Apacheはスレッドを使わずに、1つの親プロセスとリクエストを受け付ける複数の子プロセスで動作します。ここでは以下のコマンドを用いてApacheの子プロセスの平均メモリ使用量をKB単位で調べます。
# ps aux | grep [h]ttpd | grep [a]pache | awk 'BEGIN{x=0}{x+=$6}END{ print x/NR }'
24564.8
設定見直しに必要な情報がわかったところでApacheの最大子プロセス数を計算します。
Apacheの最大子プロセス数 : P  = 
Apacheに割り当て可能なメモリ量 / Apacheの子プロセスあたりの平均メモリ使用量
親プロセスのメモリ使用量も計算に入れるべきですが、子プロセスの総メモリ使用量に対して小さいことが多いため、今回は誤差に含めています。また計算結果が小数になる場合には整数に切り上げてください。
求めたApacheの最大子プロセス数Pを基にして設定を変更しましょう。設定すべきファイルは/etc/httpd/conf/httpd.confです。Apache2.2のプロセス数に関するデフォルト値は以下の通りです。
<IfModule prefork.c>
StartServers                               5
MinSpareServers                    5
MaxSpareServers                10
ServerLimit                       256
MaxClients                       256
MaxRequestsPerChild  10000
</IfModule>
それぞれの設定の意味は以下の通りです。
StartServers       : 
起動時に作成する子プロセス数
MinSpareServers    : 
リクエスト待ち状態の子プロセスがこの数値より少ない場合は新しく子プロセスを作成する
MaxSpareServers    : 
リクエスト待ち状態の子プロセスがこの数値より多い場合は超過した子プロセスを終了する
ServerLimit        : 
起動可能な子プロセスの最大値、変更には再起動が必要
MaxClients         : 
起動可能な子プロセスの最大値、リロードで変更可能
MaxRequestsPerChild : 
子プロセスがこの回数までリクエストを受け付けたら、子プロセスを終了する
これらの設定を次の値にしましょう。計算結果が小数になる場合には整数に切り上げてください。
<IfModule prefork.c>
StartServers                             P×5/256
MinSpareServers             P×5/256
MaxSpareServers               P×10/256
ServerLimit                                           P
MaxClients                                            P
MaxRequestsPerChild          1000
</IfModule>
perlやphpなどスクリプト系言語を利用する場合にはメモリリークが発生しやすいと言われているため、ここではMaxRequestsPerChildをデフォルト設定より小さくしています。
このように設定を行うことでトラブルを防止できます。この機会にApacheの設定を見直してみませんか。
参考文献
http://httpd.apache.org/docs/2.2/mod/mpm_common.html
http://httpd.apache.org/docs/2.2/mod/prefork.htmlhttp://www.math.kobe-u.ac.jp/~kodama/tips-free-memory.htmlTIS株式会社 コーポレート本部 戦略技術センター
小林 達
http://www.tis.co.jp/続きを隠す<<