Apache 2.4.1のスループット評価(旧ApacheとNginxとのベンチマーク比較)

久々のApache HTTP Server 2.4.1という安定版がリリースされたので、早速ベンチマーク評価を行う。今回はevent_mpmのExperimentがとれて、晴れてデフォルトMPMになったのでそれを使ってみたい。

日本一(ひょっとすると世界一)早いApache 2.4.1 event_mpmのレビューを意識してみた。

はじめに

個人的にも、event_mpmが採用されたことに最も注目している。event_mpmは非同期型のIO処理をしていて、nginxに近いアーキテクチャをとっている。厳密には、nginxの非同期と比べた場合、nginxは徹底的にノンブロッキング(accept4を使う等)してworkerスレッドで次々と並列処理していくのに対し、event_mpmは一部の処理のみをノンブロッキングにしているため、時々workerスレッドをセッションが占有してしまうという意味で、nginxの徹底された並列処理には劣ると考えられる。

しかし、安定性に定評のあるApacheが久々に自信を持ってリリースした(2.4.1リリースまでの度重なる議論をMLで僕も見ていたので)ので、期待してしまう。

実験

まず、単純な静的ファイルへのリクエストの処理はnginxの方がは早いと予想できる。しかし、大量のアクセスがあった場合の安定性や性能劣化がWebサーバにとっては重要なファクターである。とにかく機能を落としせば単一のリクエストの処理は早くなるのは当たり前だからだ。

そこで、今回は新旧ApacheとNginxの静的コンテンツに対するスループット性能を比較してみた。クライアントサーバから静的コンテンツに対して、httperfを使って1秒間に複数のリクエストを行い、その数を変動させて、サーバ側が1秒間に返すことのできたレスポンス数を計測した。Apach 2.4.1(event_mpm)とApache 2.2.3(prefork_mpm)、Nginx1.0.12のスループットを比較した。

静的コンテンツは適当にこんなHTMLファイルを作成した。

実際に、httperfで測定する際のベンチマークスクリプトを載せておく。今回は、Request per Secondに注目した。それぞれ3つのWebサーバソフトウェアを80と8080と8888のポートでListenするようにした。

[program lang=’perl’ escaped=’true’]

#!/bin/sh

RESULT='./result.txt'

for port in 80 8080 8888
do
    #for count in 1000 2000 3000 4000 5000 6000 7000 8000 9000 10000
    #for count in 11000 12000 13000 14000 15000 16000 17000 18000 19000 20000
    for count in 21000 22000 23000 24000 25000 26000 27000 28000 29000 30000
    do
        echo -n "$port $count " >> $RESULT
        httperf --rate $count --num-conns 25000 --server ipaddr --port $port --uri=/test.html ¦ grep "Request rate:" >> $RESULT.$port
        sleep 60
    done
done

[/program]

例えば、1000requests/secに対して、1000responses/sec出ていれば、スループットは100%だといえる。

Apacheやnginxの各設定はデフォルトの設定を用いており、評価には以下のようなスペックのハードウェアを用いた。

結果

それでは計測結果である。

 

 

赤色の数値はスループットが100%出ていない値を示している。

グラフを見て頂くとわかる通り、スループット性能はなんとApaceh2.4.1のevent_mpmが一番優秀で、次いでnginxであった。nginxは19000requests/sec当たりでガクっと処理性能が低下しているが、Apache2.4.1は24000requests/secまで100%のスループットを発揮できている。これは個人的に素晴らしいと思った。

また、Apache2.2.3のpreforkがrateを増やせば増やすほど、かなり不安定(ある意味安定)な挙動をしていた。

簡単な考察

この挙動の考察は、とりあえず日本一早く検証結果を公開したいという意味で、きちんと考察していないのが正直なところだ。

preforkのデフォルトの設定は、MaxRequestsPerChildが4000になっているため、その設定によって定期的にプロセスの生成・破棄が生じ、スループットが低下したのではないかと、まずは予想している。

また、nginxのスループットがガクっと落ちるところまでは、単位時間当たりの処理速度はnginxが速かったように思う。きちんと処理にかかった時間で処理数を割れば、速度が計測できたと思うが、今回は省略している。

いずれにせよ、Apache2.4.1は大きく性能改善がなされ、大量のアクセスが来た場合の処理耐性はnginxよりも良いということになる。

一旦は、このようなスループットに関する簡単な評価にとどまるが、ある程度の今後の性能評価に参考になる値は得られたのではないかと考えている。