Skip to content

Instantly share code, notes, and snippets.

@sonots

sonots/raptor.md Secret

Last active August 29, 2015 14:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sonots/18029b4d4c25700e1df4 to your computer and use it in GitHub Desktop.
Save sonots/18029b4d4c25700e1df4 to your computer and use it in GitHub Desktop.

ISUCONでUnicornをRaptor(Phusion Passenger 5)化したときのパフォーマンス

現実的な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 に変更)
  5. kazeburo の術 を適用(raptor on nginx に変更) 追加

で比較する

Raptor への切り替え(standalone)

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 にする。

Raptor on Nginx (追加)

passenger を nginxに組み込んで動かす

2.5. Generic installation, upgrade and downgrade method: via RubyGems の手順で

gem install passenger --pre -v 5.0.0.beta1

nginx を passenger module 付きでビルドしなおす。nginx は消さなくてもいいよ、と書いてあったがいちおう消しておいた

sudo yum remove nginx

g++ がない、と怒られたのでいれておく. インストール先ディレクトリも作っておく

sudo yum -y install gcc-c++
sudo mkdir /opt/nginx
sudo chmod a+w /opt/nginx

passenger gem に入っている以下のコマンドでビルド&インストール

$ passenger-install-nginx-module --auto

nginx.conf を以下のように変更 (kazeburo の術仕様)

worker_processes  1;

events {
  worker_connections  10000;
}

http {
  passenger_root /home/isucon/.local/ruby/lib/ruby/gems/2.1.0/gems/passenger-5.0.0.beta1;
  passenger_ruby /home/isucon/.local/ruby/bin/ruby;
  include     mime.types;
  access_log  off;
  sendfile    on;
  tcp_nopush  on;
  tcp_nodelay on;
  etag        off;
  
  server {
    listen 80;
    root /home/isucon/webapp/ruby/public;
    passenger_enabled on;

    location ~ ^/(stylesheets|images)/ {
      open_file_cache max=100;
    }
  }
}

public ディレクトリが config.ru と同じ階層にないとダメなので、symbolic link をはってごまかす

ln -s /home/isucon/webapp/public/ /home/isucon/webapp/ruby/

起動

sudo /opt/nginx/sbin/nginx

ベンチマーク結果

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

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

passenger module 組み込みの nginx をビルドして動かしてみたが、スコアは変わらなかった。

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 に転じるともっと得点が伸びる期待がある。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment