JRuby と CRuby の Rails アプリの性能比 (並列度との関係)

前回の記事では、Apache Bench で並列度を 10 に固定した状態で、アプリケーションサーバごとの render :text => 'xxx' の性能比をみてみましたが、Charles Nutter さんからもコメントをもらったので、並列度に応じた性能の変化を調べてみました。

  • Charles O Nutter 2009/01/31 02:56

You may want to try running your benchmark with a higher concurrency. GlassFish does better and better as the number of concurrent requests is increased.


環境は相変わらず Core 2 DuoiMac 上で、アプリも ab も動かしてるので、いっぱいいっぱいになってしまっているところもありますが、クライアントからの同時接続数の増加にともなうアプリケーションサーバの性能変化について、以下の結果が得られました。


CRuby では、Mongrel の場合、並列度があがるほど性能が明かに劣化しますが、Thin はなかなかいい感じです。一方 JRuby では、GlassFish は Thin に迫るいい結果です。ちなみに server オプションで動かしました。
ざっと見た限り、CRuby + Thin も JRuby + GlassFish も、並列度 100 くらいでは性能劣化の気配はほとんど見られませんでした。
# GlassFish はメモリの使用量が増えてくると性能劣化してきますが、それはまたそれとして...。 (^^;



もう少しコア数の多い環境で比べてみたくなってきましたね...。


結果

並列度 CRuby+Mongrel CRuby+Thin JRuby+GlassFish
1 357.16 427.33 220.95
2 331.06 445.27 364.69
5 319.43 455.82 415.80
10 313.83 461.64 440.32
20 307.54 461.57 443.40
50 293.56 461.36 435.78
100 274.87 457.43 421.24

# 表の数字は、下記で取得した Requests per seconds [#/sec] の平均値となります。

% ab -n 10000 -c 並列度 http://localhost:xxx

環境

  • 処理系、ライブラリのバージョンは以下のとおり
% ruby186 -v
ruby 1.8.6 (2008-08-11 patchlevel 287) [i686-darwin9.6.0]

% jruby -v
jruby 1.1.6RC1 (ruby 1.8.6 patchlevel 114) (2008-12-03 rev 8263) [i386-java]

% java -version
java version "1.6.0_07"
Java(TM) SE Runtime Environment (build 1.6.0_07-b06-153)
Java HotSpot(TM) 64-Bit Server VM (build 1.6.0_07-b06-57, mixed mode)

% $GLASSFISH_HOME/bin/asadmin version
バージョン = Sun GlassFish Enterprise Server v2.1

% gem list --local

*** LOCAL GEMS ***

mongrel (1.1.5)
rails (2.2.2)
thin (1.0.0)
warbler (0.9.12)
...

# 目ぼしいものを適当に抜粋

測り方

  • render :text => 'Hello World!' だけのアクションを用意
  • ab -n 10000 -c 10 http://localhost:xxx で -c に渡す値を 1, 2, 5, 10, 20, 50, 100 に変化させて計測
  • ab と Rails は同一筐体で動作
  • Rails の threadsafe オプションは uncomment (つまり利用)
  • 当たり前だけど、production 環境
  • 各並列度ごとに 5回計測して、最小/最大値を除外して平均値を算出 (5回分すべてのデータは下記参照)
  • JRuby + GlassFish はメモリ使用量が増えると性能が劣化したので、その傾向がではじめたら GlassFish を再起動して再計測

詳細

左から順に、並列度、最小/最大値を除外した平均値、全計測結果(5回分) です。

concurrency:1 average:357.16 <= [357.32, 355.97, 356.73, 357.45, 357.43]
concurrency:2 average:331.06 <= [331.27, 332.16, 331.48, 330.42, 328.91]
concurrency:5 average:319.43 <= [321.23, 318.95, 320.2, 318.73, 319.13]
concurrency:10 average:313.83 <= [314.14, 313.71, 313.49, 314.03, 313.74]
concurrency:20 average:307.54 <= [308.16, 307.94, 306.59, 304.89, 308.08]
concurrency:50 average:293.56 <= [295.57, 292.58, 292.52, 293.64, 294.47]
concurrency:100 average:274.87 <= [276.25, 274.7, 275.47, 274.31, 274.44]
  • CRuby + Thin
concurrency:1 average:427.33 <= [426.65, 427.25, 428.03, 426.7, 429.2]
concurrency:2 average:445.27 <= [443.02, 445.57, 443.83, 448.66, 446.41]
concurrency:5 average:455.82 <= [456.15, 458.36, 454.6, 455.05, 456.25]
concurrency:10 average:461.64 <= [462.86, 461.37, 445.55, 461.57, 461.97]
concurrency:20 average:461.57 <= [462.58, 460.16, 463.06, 461.96, 459.45]
concurrency:50 average:461.36 <= [461.56, 461.09, 462.14, 460.27, 461.43]
concurrency:100 average:457.43 <= [457.8, 458.65, 456.21, 458.28, 455.2]
concurrency:1 average:220.95 <= [150.02, 204.79, 225.9, 232.15, 232.94]
concurrency:2 average:364.69 <= [362.36, 358.22, 374.37, 360.24, 371.46]
concurrency:5 average:415.80 <= [403.02, 420.01, 419.93, 407.47, 423.66]
concurrency:10 average:440.32 <= [434.1, 429.52, 444.21, 447.44, 442.66]
concurrency:20 average:443.40 <= [441.94, 420.8, 442.01, 446.26, 447.42]
concurrency:50 average:435.78 <= [419.98, 435.91, 438.71, 433.98, 437.44]
concurrency:100 average:421.24 <= [411.54, 425.45, 426.73, 432.83, 393.01]