現実的なWebサービス環境において、Raptor(Phusion Passenger 5)によるパフォーマンス向上がどの程度のものか調査するために、 ISUCON4 の予選問題のうち、Unicorn 部分を Raptor 化してベンチマークをとってみた。典型的なWebサービスシステムの3層構造(Proxy, App, DB)を構築し、ベンチマーカーにより高ワークロードを実現できるので、ISUCON の予選問題は適当な題材といえる。

ベンチマーク条件

基本的に、ISUCON4予選のレギュレーションに則る。

インスタンスタイプ: m3.xlarge CPU: Xeon E5-2670 v2 @ 2.50GHz 4 vCPU メインメモリ: 16GB RAM ストレージ: EBS Magnetic volumes OS: Amazon Linux 3.14.19-17.43

* ここまで y_uuk1 テンプレ

  1. ISUCON4 予選のデフォルト状態(unicorn)
  2. ISUCON4 予選のデフォルト状態(raptor standalone に変更)
  3. kazeburo の術 を適用(unicorn)
  4. kazeburo の術 を適用(raptor standalone に変更)

で比較する

Raptor への切り替え

典型的な ISUCON 構成だと前段に nginx がいるので、今回は raptor を standalone で動かすものとする。ToDo: passenger on nginx 構成を試す

Gemfile

- gem "unicorn"
+ gem "passenger", "= 5.0.0.beta1"

Procfile (unicorn_config.rb で worker_processes 10 となっているので --min-instances を 10 にしてみた)

- unicorn: bundle exec unicorn -c unicorn_config.rb -p 8080
+ passenger: bundle exec passenger start --min-instances 10 -p 8080

kazeburo の術 Ruby 版

ISUCON4 予選でアプリケーションを変更せずに予選通過ラインを突破するの術 から以下を除外

  • memcached
  • perl 関連 (cpanfile や app.psgi の変更)
  • /etc/supervisord.conf の変更

env.sh に以下を追加

export RACK_ENV=production

Procfile を以下のように変更

unicorn: bundle exec unicorn -c unicorn_config.rb -l /dev/shm/app.sock

supervisord でアプリを再起動

sudo supervisorctl restart isucon_ruby

なお、passenger を unix domain socket に変える場合は -p 8080 を -S /dev/shm/app.sock にする。

ベンチマーク結果

  • benchmarker の workload 指定は全て 8 (一定)
構成スコア
unicorn(default)2433
raptor standalone(default)2483
unicorn(kazeburo)38456
raptor standalone(kazeburo)40141

unicorn の場合は kazeburo の術で4万超えていなかったが Raptor で 4万超えの結果となった。Introducing Phusion Passenger 5 beta 1, codename “Raptor” の記事で彼らが「Hello World ベンチの結果なんてたいして意味がないんだよ」と言っていた通り現実に近いアプリで評価すると確かに4倍とはならなかったが、それでも ISUCON 民としてこの結果はうれしい。

Raptor のエラー

なお、Raptor で以下のようなエラーが出ていた。こちらの Issue で対応中のようだ。

03:33:52 passenger.1 | App 6297 stderr: /home/isucon/.local/ruby/lib/ruby/gems/2.1.0/gems/passenger-5.0.0.beta1/lib/phusion_passenger/config/system_metrics_command.rb:32:in `exec'
03:33:52 passenger.1 | App 6297 stderr: : No such file or directory - /home/isucon/.local/ruby/lib/ruby/gems/2.1.0/gems/passenger-5.0.0.beta1/buildout/support-binaries/PassengerAgent (Errno::ENOENT)
03:33:52 passenger.1 | App 6297 stderr:         from /home/isucon/.local/ruby/lib/ruby/gems/2.1.0/gems/passenger-5.0.0.beta1/lib/phusion_passenger/config/system_metrics_command.rb:32:in `run'
03:33:52 passenger.1 | App 6297 stderr:         from /home/isucon/.local/ruby/lib/ruby/gems/2.1.0/gems/passenger-5.0.0.beta1/lib/phusion_passenger/config/main.rb:75:in `run!'
03:33:52 passenger.1 | App 6297 stderr:         from /home/isucon/.local/ruby/lib/ruby/gems/2.1.0/gems/passenger-5.0.0.beta1/bin/passenger-config:37:in `<main>'

また、これとはおそらく原因が別だと思われるが benchmarker では以下のような結果がでて、ちょくちょく fail していた。

04:57:45 type:fail      reason:Expected selector is not found: //*[@id='notice-message']        method:GET      uri:/
04:57:45 type:fail      reason:Expected html text is match: This account is locked., got Wrong username or password     method:GET      uri:/

画面を直接さわると正常に動いているように見えるので、並列で高負荷をかけた時の問題だろうか、と推測している。

04:45:33 type:score     success:185820  fail:5584       score:40141

stable 版になって、全てが success に転じるともっと得点が伸びる期待がある。

ToDo

Passenger on Nginx を試す