event MPM のチューニング

やりたいこと

サーバが重くなるのはしょうがないとして、落ちないようにしたい。
※ prefork MPMの時はデフォルトだとabを利用した負荷テストでApacheが落ちたけど、event MPMだとデフォルトの状態で、preforkの時と同じ条件の負荷テストで落ちることはなくなっていたので進歩を感じてうれしく思った。

使用するディレクティブ

ディレクティブ名説明
ThreadsPerChild各子プロセスで用意されるスレッド数を制限する。
デフォルト値:25
計算式:ThreadsPerChild = MaxRequestWorkers ÷ ServerLimit
MaxRequestWorkers同時接続数の最大値を制限する。
計算式:MaxRequestWorkers = ServerLimit × ThreadsPerChild
StartServers起動時のプロセス総数を設定する。
デフォルト値:3
MinSpareThreadsリクエストに応答することのできるアイドルスレッド数の最小値を設定する。
MaxSpareThreadsリクエストに応答することのできるアイドルスレッド数の最大値を設定する。
ServerLimitサーバプロセス数の上限を制限する。
計算式:ServerLimit = MaxRequestWorker ÷ ThreadsPerChild
MaxConnectionsPerChild1つのプロセスが受け付けることのできる接続数を設定する。
0が指定された場合、プロセスはずっと再利用されることになる。
もしメモリリークが起こった時のためにこの設定を行う。
AsyncRequestWorkerFactor各プロセスの同時接続数を制限する。
デフォルト値:2

/etc/php-fpm.d/www.conf

下記内容で設定している(プロセスの数は2で固定される)
pm = static
pm.max_children = 2

使用メモリ量の考え方

概要

※ この考え方が間違っている可能性もあるので、注意。

Webサーバ以外でも使用する予定なら、それを踏まえてどれだけメモリを使いたいか考える。
1GBのメモリしか積んでいないので、とりあえず600MBをWebサーバとPHP-FPMで使うことにする。

使用メモリ量を確認するために、下記のabコマンドを利用して負荷をかけた。

$ ab -n 100 -c 100 http://ドメイン名/

php-fpmの使用メモリ量メモ

実行ユーザがrootのプロセスが1つ、
実行ユーザがapacheのプロセスが2つ、
合計3つのプロセスが走っていた。
rootのプロセスは66400KiB使用していた。
apacheの1つめのプロセスは59880KiB、2つめのプロセスは58664KiB使用していた。
合計は127,236KiB。
PHP-FPMのプロセス数は2で固定しているので、
サイトに大きな変更をしない限りメモリ使用量も大きく変わらないはず。

rootのプロセスが70MB使用、
apacheのプロセスが1個あたり80MB使用すると考えて、
PHP-FPM全体でのメモリ使用量 = 70MB + 80MB × 2 = 230MB となる。

Apacheの使用メモリ量メモ

600MBのメモリをApacheとPHP-FPMで使いたいので、
Apacheに割り当てるメモリ量 = 600MB – 230MB = 370 MB となる。

Apacheのrootのプロセスは約15MB使用、
Apacheのapacheユーザのプロセスが1個あたり40MB使用すると考えると、
(実際には20MBぐらいだったけど)
プロセス数 = 370MB ÷ 40MB = 9.25 となるので、
Apacheのapacheユーザのプロセス数は9個とする。

各ディレクティブの値の考え方

Apacheのプロセス数の上限は9個で決定したので、
ServerLimitの値は9になる。

ThreadsPerChildの値はデフォルトの25のままにしておく。
負荷をかけた時もこの値なので、25より大きな数値にすると前回考えた使用メモリ量が参考にならなくなる。

MaxRequestWorkers = ServerLimit × ThreadsPerChild
で計算するので、
MaxRequestWorkersは225になる。

Apacheのmod_statusによるステータスページを見た限りでは、
1プロセスあたりのスレッド数は25が区切りになっているようなので、
MinSpareThreadsは25にする。

MaxSpareThreadsの値は単純にサイトの規模を考えたら、
MinSpareThreadsの2倍で良さそうということで50にする。

StartServerのデフォルト値は3なので、とりあえずデフォルトより低い2とする。

MaxConnectionsPerChildはMinSpareThreadsの4倍の100とする。

AsyncRequestWorkerFactorはデフォルトの2のままとする。

最後に

後はこれらの値をhttpd.confで、各ディレクティブを使って設定すれば良い。
少なくとも下記コマンドではサーバが落ちることはなかったし、Failed requestの値も0だった。

$ ab -n 200 -c 200 http://ドメイン名/

ただし、下記コマンドではサーバは落ちなかったが、Failed requestの値が3になっていた。

$ ab -n 300 -c 300 http://ドメイン名/

また、freeコマンドでモニタリングしたところ、
負荷をかけている間、120MBほど未使用メモリがある状態だった。
WordPressのサイトだけどキャッシュ機能を使っていない状態でこの結果なので、
しばらくは大丈夫だろうと思っています。

コメント

タイトルとURLをコピーしました