ちょっと間が空いてしまいましたが、久々にメモを残しておきます。
Apacheが遅い/止まると言われてしまいまして
現在進めているプロジェクトで、やや大きめのサーバ構築をしてたんですが、ちょくちょく「レスポンスが遅い/Apacheが止まる」と言われてしまい、うーんなんでだろうと色々試行錯誤していたメモ書きです。 ちなみにDBはMySQL-Cluster、サーバサイドはPHPです。
(本当はPound側とかMySQL側にもいくばくかの問題があったのですが、主な問題はここだったのでほかは省略)
MPMの話だった
原因に気づいたのはパフォーマンスチューニングの最中でした。Apache Benchでもそもそ検証してたんですが、
ab -n 10 -c 2 http://localhost/xxx
という小さめな条件振りでもレスポンスに失敗するケースに陥りました。それなりのスペックを積んでるマシンなので、これはおかしいと思いながら設定周りを見直すことに。とりあえず以下のようにhttpd.confを書きました。
<ifmodule prefork.c>
StartServer 5
MinSpareServers 5
MaxSpareServers 10
ServerLimit 200
MaxClients 200
</ifmodule>
ここで罠に気づいた方もいらっしゃるかと思いますが、もうしばらくお付き合いください。 まぁ何度やってもパフォーマンスは改善せず。なんだろーと色々試行錯誤してるうちに、ふとIfModuleの項を外してhttpdをリスタート。すると…
Apacheのconfiguration Error
「え、なになになんなの?prefork.cないわけ?」と思うわけです。マルチプロセッシングモジュール (MPM) - Apache HTTP サーバによると、Unix系はデフォルトでMPMはpreforkって書いてありますよね(この時点で2.2のドキュメントであることに気づきませんでした…)。で、今回ソースからインストールしているのはApache2.4.4。まさかと思いMPMをチェックすると、
# /usr/local/httpd/bin/apachectl -V
> Server MPM: event
え、eventってなんですか僕workerかpreforkしか知らないんですが。調べると非同期I/Oとかできる新しいMPMみたいですね。以下のサイトを参考に。
どうやら2.4からはevent MPMデフォルトになっているようです。全く知りませんでした…。で、preforkを使うように再コンパイル。
./configure prefix=/usr/local/httpd ..... --with-mpm=prefork
という感じでオプションをつけて再コンパイルをすると無事preforkに。abコマンドもちゃんとレスポンスを返すようになって事無きを得ました。ちなみに、サーバーサイドがPHPの場合(mod_php)の場合はMPMはprefork一択なんです。この辺りは以下のサイトが詳しいです。
あとはabを繰り返してパフォーマンスチューニングをすることでレスポンスは改善されましたとさ。あ、あとはMySQL-Clusterの設定が重要なファクターでもあったんですが、それはまた機会があれば。