Apache周りの微調整

メインメモリーが128MBでvSwapが256MBといった環境下で如何に快適にリソースマネジメントを行うかというのが当面のテーマだったなのだが、Apacheのプロセスコントロールをかなり切り詰めても、意外と動作するという点は、前回通り継承し、preforkモデルで以下のパラメータでそこそこの結果が得られていた。

<IfModule prefork.c>
StartServers 1
MinSpareServers 1
MaxSpareServers 1
ServerLimit 25
MaxClients 25
MaxRequestsPerChild 1000
</IfModule>

しかし、この状態で、しばらくの間放置すると、httpdプロセスが3スライス程度走行し、メインプロセスのhttpdの専有メモリーが何時までたっても開放されず、定常的な状態で、100MB程度の運用に留まることがわかった。
実際には、一つのhttpアクセスが生じた後、更にアクセスが有った場合、最大値でもう少し大きくなってしまい、極端な場合、メモリリークが発生しており、Apache管理外のメモリーとなってガベージしてしまうことがあるようだ。
もちろん、ある程度のプロセスコントロールは完全に動作しているのだが、大きなPHPプログラムが走行した後にもなおかつメモリーを開放できないといった事象が見られた。
そこで、今回は、MaxRequestsPerChildをもう少し切り詰めてみようという試みで、極端にこの値を”1”までつまり1回のアクセスが終わるか終わらないうちに、メモリーを開放させるようにして動作を見た。
思ったように、プロセス専有メモリーは、めまぐるしく変化し、大きなプロセスが発生した後も速やかに、メモリーを開放する事ができる。ただし、この値は、あまり小さすぎると、いちいち最初から同じプログラムを読み込むので、極めて効率が悪い。
そのようなことから、色々と試行錯誤した結果、WordPressの仮想サイトが3程度で、時に、WordPressの記事投稿などの編集を行なったり、Ajaxplorerがストレス無く動作するパラメータを求めた結果、概ね”256″あたりが効率的で、多くても少なくても良くない結果となったが、ほぼこの周辺で、微調整を行うと、定常プロセスの専有メモリーが10MB単位で変動することがわかった。
結果、以下の様な値にしてみた。

<IfModule prefork.c>
StartServers 1
MinSpareServers 1
MaxSpareServers 1
ServerLimit 25
MaxClients 25
MaxRequestsPerChild 128
</IfModule>

かなり少ないように感じると思うが、実は、これで良く、大手のレンタルサーバーでも、この値を大きくしないことで、ひとつのサーバー上で、100人~150人のユーザーをさばいているらしい。
結果的に、OPcache + APCuといったPHPが最適化された環境下では、Apacheそのものに頑張ってもらうよりは、PHP側の最適化によって、プロセスの一部をCacheで担い、Apacheには一定のリクエストに達したら速やかにメモリーを開放してもらったほうが効率的であるようだ。

たったこの1行の変更で、定常的なメモリー占有量は、大幅に減り、WordPress編集時でも、100MBを切ることができる事がわかった。また、Ajaxplorerアクセス終了時には、定常値の50MB~70MB程度へ速やかに移行する。
”128”では多少きついかとも思ったが、この値は、同時アクセス数に応じて微調整することが好ましく、放っておくとhttpdの専有メモリーが肥大化して行くので、都度、レスポンスを見ながら、最適値を変えるのが良い。

しかし、恐るべきOPcache + APCuである。

Apache最適化も一応済んで、行き詰まったら、今回のMaxRequestsPerChildを変更してみると良いかもしれない。