引き続き Apache 2.4.1のスループット評価(旧Apacheと動的コンテンツ処理性能比較)

前回の記事「Apache 2.4.1のスループット評価(旧ApacheとNginxとのベンチマーク比較)」を非常に多くの方に見て頂いており、こういう情報が重要なんだなぁ、としみじみ思った。多くのオープンソースを使わしてもらっているので、こういう形でフィードバックしていけたらよいな。参考にして頂いてありがとうございます。

今回は、前回の記事に続き、個人的にも非常に興味のあるApache2.4.1の「動的コンテンツのスループット」がどの程度なのかを評価したいと思う。

※いくつかの検証を追加したのと、細かい部分で比較の仕方がよろしくなかったので修正を加えました。

■ 修正と追記箇所(2012年3月2日)
・PHPのバージョンを5.3.10に統一(思っていた以上にバージョン間でパフォーマンスに差があった)
・Apache 2.4.1 と2.2のpreforkによる検証を追加
・Apache2.4.1のpreforkとeventの比較を追加
・ついでにphp5.1系と5.3.10の性能比較を追加

今回は動的コンテンツということで、nginxは評価せず、Apache2.4.1と2.2系の比較を行った。両方のMaxClientsの値を256に設定し、その他の設定は基本的にデフォルトのままにしている。Apache2.4.1を気軽に使ってもらうためにも、コンパイルの仕方を簡単に載せた。

まずは、APRとAPR-Utilsをコンパイルしておく。もともとあるAPRと被らないように、PREFIXで別のディレクトリを指定する。今回は、せっかちな人用ということで、一番簡単にできるコンパイルオプションにした。tar.gzはそれぞれASFのサイトからダウンロードする。

  • APRのコンパイル
tar zxvf apr-1.4.6.tar.gz
cd apr-1.4.6/
./configure --prefix=/usr/local/apr
make
make install
  • APR-Utilsのコンパイル
tar zxvf apr-util-1.4.1.tar.gz
cd apr-util-1.4.1/
./configure --prefix=/usr/local/apr
make
make install
  • 最後にApache2.4.1のコンパイル
tar zxvf httpd-2.4.1.tar.gz
cd httpd-2.4.1/
./configure --prefix=/usr/local/apache2.4 --with-apr=/usr/local/apr --with-apr-util=/usr/local/apr
make
make install

上記で、Apache2.4.1を利用することができる。以下のコマンドでApacheを起動。

/usr/local/apache2.4/bin/apachectl start

実験は以下の2種類を実施。

CGIのスループット

まずは、Webサーバ上で動作するプログラムの実行方式として定番のCGIに対してスループットを評価した。前回と同様のハードウェア上でhttperfによるベンチマークを行った。リクエスト対象のファイルは、Apache2.4.1にデフォルトでついている以下のようなサンプルCGIを採用した。

2.4.1はmod_cgid、2.2.3はmod_cgiを読み込んだ。ベンチマークに利用したスクリプトは以下の通り。

#!/bin/sh

RESULT='./result.txt'

for port in 80 8080
do
    for count in 100 200 300 400 500 600 700 800 900 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 2000
    do
        httperf --rate $count --num-conns 4000 --server ipaddr --port $port --uri=/cgi-bin/test.cgi | grep "Request rate:" >> $RESULT.$port
        sleep 60
    done
done

実行結果のデータとグラフは以下のようになった。

 

赤色の値は、前回と同様スループットが100%でなかった値を示している。

どうやら、CGIのスループットは旧Apacheの方が良いようだ。この実験だけではなんとも言えないので、次の実験も行った。

Apache2.4.1をprefork_mpmにして、同様のスループット評価を行った。以下がその結果である。

Apache 2.4も2.2もpreforkにしたとしても、ほとんど結果は変わらなかった。基本的にはCGIにおけるプロセスの生成・破棄の処理は、大きなボトルネックになる箇所なので、その処理があるにも関わらずここまでスループット性能に差がでるということは、ap_hook_handler当たりでの動的コンテンツの扱いで処理が大幅に増えているのではないかと予想できる。

 

DSO(PHP)のスループット

次にDSOのスループットを測定した。DSOを特徴を簡単に説明すると、CGIのようにプログラムを実行する際に、新たにプロセスを生成してから実行するのではなく、サーバプロセスそのものに各種インタープリタ(今回の場合はPHP)を組み込んでおくことで、プロセスを新規で生成することなく、直接サーバプロセス(スレッド)がプログラムを実行できる方式だ。そのため、プロセス生成・破棄がボトルネックとならず、高速に動作する。この実験を行うことで、CGIを実行するためのforkからexecveに至るまでのルーチンに差があるのか、動的コンテンツを実行するルーチン(静的コンテンツのようにファイル内容を表示するルーチンではなく)そのものに差があるのかがある程度予想できる。

phpは5.3.10を利用した。

DSOに関してはこの辺りも参考になるかもしれません。

拡張子によってApacheモジュールの処理を適応するか判断するpatch(mod_ruid2版)
mod_ruid2はgroupsを元の状態に戻せないのでpatch作成

論文等で評価を行う場合は、phpinfo()なプログラムを評価対象にすることが多いが、今回は別のApacheでphpinfo()の出力サイズが大きく変わったため、以下のような外部コマンドを実行するようなサンプルプログラムを利用した。

phpは5.3.10をApache2.4.1のapxsでコンパイルした。コンパイルオプションを参考までに載せておく。

./configure --prefix=/usr/local/php5.3.10 --with-apxs2=/usr/local/apache2.4/bin/apxs --with-openssl --with-zlib --with-gd --with-mysql --enable-exif --enable-gd-native-ttf --with-gettext --with-libxml-dir=/usr/lib/libxml2 --with-jpeg-dir --with-png-dir --with-freetype-dir --with-xpm-dir --with-png-dir --enable-zend-multibyte --enable-sysvmsg --enable-sysvsem --enable-sysvshm --enable-soap

ベンチマークに利用したスクリプトは以下の通り(もうほとんど一緒だから載せなくてもいいかな・・・)

#!/bin/sh

RESULT='./result.txt'

for port in 80 8080
do
    for count in 100 200 300 400 500 600 700 800 900 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 2000
    do
        httperf --rate $count --num-conns 4000 --server ipaddr --port $port --uri=/cmd.php | grep "Request rate:" >> $RESULT.$port
        sleep 60
    done
done

実行結果は以下のようになった。

※ Apache2.2.3のprefork_mpm側がphp5.1系になっていたのでphp 5.3.10を使った場合と差し替えました

 

やはり、Apache2.4.1でevent_mpmを組み込んだ場合は、DSOも圧倒的に旧Apacheの方がスループットが出ており、Apache2.4.1 event_mpm側の性能はあまり良くない。CGIやDSOという実行方式による差ではなく、そもそもの動的コンテンツを処理する際のルーチンが増えているのだろうか。

次に、Apache2.4もpreforkにし、Apache2.2のpreforkと、両バージョンにphp5.3.10を組み込んだ場合のパフォーマンスを比較した。preforkを使ってきている人が多いと思うので、2.4を使う場合でもpreforkを組み込む方が多いと思う。

 

event_mpmを組み込んだ場合と比べると、かなりスループットの差は少なくなっている。この結果から、Apache 2.4.1を採用する場合は、preforkによってDSO版PHPを利用すれば、それなりに今までに近い形でPHPを実行できるのではないかと思う。しかし、この結果からも2.2の方がphpをDSOで動かした場合は性能が良いことになる。Apache2.4.1におけるevent_mpmとprefork_mpmでDSO版PHPを使った場合のスループット比較は以下のグラフとなる。

以上から、Apache2.4.1でもevent_mpmとprefork_mpmでDSO版PHPを実行する場合は、スループット面で大きな差があることが分かった。ここまでやると、静的コンテンツではどうかもevent_mpmとprefork_mpmで比較したいが、それはまた時間があるときに行う。

Apache2.4.1を使う場合は、静的コンテンツ中心であればevent_mpm、動的コンテンツ中心であればprefork_mpmを使うと思っておけば良いのではないだろうか。

ちなみに、自分のミスで、Apache2.2はphp5.1を使っていたのだが、php5.1系とphp5.3.10の間でも、大きなスループットの差が生じていたので、それを参考までに載せておく。

このように、Apache2.2系に対して、PHP5.1または5.3.10を組み込んだ場合は、5.1系の方がスループットが高い事がわかる。細かい部分でphpのコンパイルオプション等で変わるのかもしれないが、参考にして頂ければと思う。

 

最後に

2.2との比較において、2.4.1は動的コンテンツの扱いが苦手になったように思える。これは、非常に気になる結果になってしまったので、今後原因を調査していきたいと思う。

「引き続き Apache 2.4.1のスループット評価(旧Apacheと動的コンテンツ処理性能比較)」への2件のフィードバック

コメントは受け付けていません。