_ Rails 2.2 RC1 を threadsafe! で使ってみた

Rails 2.1 で運用していたアプリを 2.2 RC1 にアップデートしてみたよ。デモアプリとかじゃなく、それなりにまともに運用しているサービスでやらかしてみたので、参考になる人もいるのではないかと作業の手順を晒すのです。

現状ベンチマーク

ステージング環境を ab で計測 Ruby 1.8.6 patchlevel 111 Rails 2.1.1 nginx -> unix domain socket -> thin*3 * ほぼ静的なトップページ Concurrency Level: 100 Time taken for tests: 20.756579 seconds Complete requests: 1000 Failed requests: 0 Write errors: 0 Total transferred: 2003000 bytes HTML transferred: 1640000 bytes Requests per second: 48.18 [#/sec] (mean) Time per request: 2075.658 [ms] (mean) Time per request: 20.757 [ms] (mean, across all concurrent requests) Transfer rate: 94.24 [Kbytes/sec] received * DB/memcached にアクセスにいくようなページ Concurrency Level: 100 Time taken for tests: 48.774599 seconds Complete requests: 1000 Failed requests: 0 Write errors: 0 Total transferred: 1140000 bytes HTML transferred: 778000 bytes Requests per second: 20.50 [#/sec] (mean) Time per request: 4877.460 [ms] (mean) Time per request: 48.775 [ms] (mean, across all concurrent requests) Transfer rate: 22.82 [Kbytes/sec] received

やった作業

edge rails を vender/rails 以下に展開

rake rails:freeze:edge

config/environment.rb を修正。(freeze してるので必要ないけど、将来忘れててギャッとならないように)

RAILS_GEM_VERSION = '2.2.0' unless defined? RAILS_GEM_VERSION

テスト実行。プラグイン周りでいっぱいエラーがでる。 そして以下採った対策。

activescaffold 管理ツール系で一部利用していたが、徐々に独自に作成した画面に置き換える作業を進めていたので、思い切って使わない事にした。まあ github 追っかけてたらそのうち 2.2 対応したものが出てくるはず。 gettext activescaffold の日本語化に使っていただけなので、これも使わない事にした。携帯サイトなので当面国際化は必要なさそうだし。 erubis 迷ったのだが使わない事にした。単純な置換で済むのでとりあえず素の erb に戻した。 jpmobile これは使わない訳にはいかないので、以下のパッチを作成。actionpack が結構書き換わっていたが、フックするメソッドを変更するだけですんだ。 パッチを取り込んで貰ったので最新版なら問題なく動きます。 cache_fu こちらも使わない訳にはいかないので、以下のパッチを作成 github で公開されているこちらのブランチなら問題なく動きました active-form 以下のパッチを適用 パッチを取り込んで貰ったので最新版なら問題なく動きます。

コードの threadsafe 化。 動的にクラス変数なんかを書き換えている所を直す。

config/environments/production.rb の以下の行をコメントアウト/追加

#config.action_view.cache_template_loading = true config.threadsafe! # lib 以下に俺俺クラス等置いてる場合 config.eager_load_paths << "#{RAILS_ROOT}/lib"

config/database.yml の各環境 (staging, production あたり) に以下の行を追加。(デフォルト値は両方 5)

pool: 10 wait_timeout: 5

手元の環境で RAILS_ENV=production scripts/server で動作するか確認。

ためしに ab で負荷を与えると memcache-client で例外が出た。

/usr/lib/ruby/gems/1.8/gems/memcache-client-1.5.0/lib/memcache.rb:550:in `write' /usr/lib/ruby/gems/1.8/gems/memcache-client-1.5.0/lib/memcache.rb:550:in `cache_get' /usr/lib/ruby/gems/1.8/gems/memcache-client-1.5.0/lib/memcache.rb:209:in `get'

memcache-client と cache_fu のコードを読むと、config/memcached.yml に以下の行を追加すれば良いことが解った。

multithread: true

実行環境の thin のバージョンを 1.0.0 にアップデートする。 起動オプションに --threaded --no-epoll を付ける。

作業後ベンチマーク

ステージング環境を ab で計測 Ruby 1.8.6 patchlevel 111 Rails 2.2.0 RC1 nginx -> unix domain socket -> thin*3 threadsafe! connection pool: 10 * ほぼ静的なトップページ Concurrency Level: 100 Time taken for tests: 40.824541 seconds Complete requests: 1000 Failed requests: 0 Write errors: 0 Total transferred: 2000857 bytes HTML transferred: 1640000 bytes Requests per second: 24.50 [#/sec] (mean) Time per request: 4082.454 [ms] (mean) Time per request: 40.825 [ms] (mean, across all concurrent requests) Transfer rate: 47.84 [Kbytes/sec] received * DB/memcached にアクセスにいくようなページ Concurrency Level: 100 Time taken for tests: 102.297648 seconds Complete requests: 1000 Failed requests: 0 Write errors: 0 Total transferred: 1118529 bytes HTML transferred: 777655 bytes Requests per second: 9.78 [#/sec] (mean) Time per request: 10229.765 [ms] (mean) Time per request: 102.298 [ms] (mean, across all concurrent requests) Transfer rate: 10.67 [Kbytes/sec] received

うぎゃあああああああああああああおせえええええええＥＥＥＥＥEEEEE!23333

やっぱ ruby1.8 のグリーンスレッドじゃパフォーマンスは期待できないか(ﾉД`､)

実際の使用感など

苦労した割にベンチマークでは散々な threaded rails なのですが、せっかくなので実際に本番環境で数日運用しています。

夜間のアクセスが集中する時刻には、Rails 2.1 以前だと起動している Rails のインスタンス数で捌ききれない量のアクセスが来ると、一気にサービス不能の状態に陥っていたのが、2.2 (--threaded) に変更してからは遅くてもなんとか応答を返そうと努力してくれるようになった感じ。

現状7台のマシンに分散して 350 インスタンス起動。それなりの並列度があればパフォーマンスの低下は全く気にならない。

まだ暫くは、従来どおり Rails インスタンスの数で並列度を確保しておいて、繁忙時にサービス停止しないよう threaded (コネクションプーリングも控えめに 2~3 くらい) で運用するような加減が良い塩梅なのかもしれない。

Ruby1.9 や JRuby で動かせば、もっと劇的に並列度もパフォーマンスも改善されるのかな(;´Д`)さすがに今それをやる勇気も根性もでないが

まとめ

Rails と俺たちの戦いはまだ始まったばっかりだ！(ﾟДﾟ)DHH 先生の次回作にご期待ください！