#CookpadTechConf 2016で「Railsアプリ開発環境の高速化」について話した

クックパッドの社員が発表するCookpad TechConfというイベントの第一回が今日行われ、「Railsアプリ開発環境の高速化」というテーマで話してきた。

開発環境の改善について

僕が技術部に入る前、サービス開発をやる中で一番不満だったのが開発環境のパフォーマンスだったので、技術部に配属されたころからこの仕事をやりたいと思っていた。

今回は先輩方が既に行っていた開発環境のパフォーマンスチューニング - クックパッド開発者ブログの一部を紹介しつつ、その続きとして自分がやってきたことを発表した。 業務で出した成果のうちいままで外部で発表したのはbyebugの高速化くらいだったので、普段僕がどんな仕事をやっているのか紹介する良い機会になった。

発表内容の補足

思ったより15分の枠で話せたことが少なかったので、発表内で話し足りなかったことについて書く。

libsassおすすめです

急いでて全然ちゃんと紹介できなかったんだけど、この発表の中で普段Railsアプリの開発をやっている人にとって目新しいことは多分libsassしかない。これはsassのC++実装で、今週sass gemからの移行が完了し、いれた次の日に同僚から突然速くなってよかったというフィードバックがあった。

libsassが良い理由

おすすめする理由は以下の4つある。

  • とにかく速い
  • Cookpadのcss全体のうち挙動に影響のある非互換が、関数による色の計算が少しズレることだけ
  • gcc 4.6以上かclangならいまのところ普通にコンパイルできている
  • Sprockets 4で標準サポートされるのでレールに乗ってる

導入効果

Sprockets 3だとなぜかlibsass以外のレイヤー*1が遅く、期待より効果が少し低かったのだけれど、それでも改善前のアセットプリコンパイルの71%がcssに費されていたので資料に書いた通りそこそこインパクトがあった。Sprockets 2だと cssを生成する時間が604秒から140秒に短縮される *2

railsで使う場合は今はsassc-railsを使うと良い。なおsassc-rubyを普通に使うとscssのシンタックスエラーでscssでないコードがエラー画面に出てしまうのでパッチを投げていて、これを反映したフォークを運用している。

RubyのGC使います

発表内容的に完全に脱線なので質問されたら話そうと思っていた内容なんだけど、Cookpadでは例えば GC を止める・Ruby ウェブアプリケーションの高速化 - 2nd lifeにある通り1/23現在リクエスト処理中はGCが止まっていて、これを来週変える予定であるという話。

gctoolsがRuby 2.1でしか動かない

開発環境でOut-of-band GCもどき *3 を試していたとき、Unicorn::OobGCのコードを読んでいたらRuby2.1以上ならtmm1/gctoolsがおすすめというコメントが書いてあった。そこで興味を持ってCookpadのRubyが2.0.0から2.2にアップグレードされた時gctoolsの検証を行ったのだけど、unicornのエラーがガンガン出たのですぐにロールバックした。

Ruby 2.2のRIncGCよさそう

それでgctoolsのissueを見てみたところ、どうもgctoolsの作者によると、Ruby 2.2で導入されたRIncGCのおかげでOobGCは不要であり、Ruby 2.2サポートはしないらしい。ちゃんとした説明はRIncGC jaを読んで欲しいのだけど、メジャーGCの長いマーク時間を解決するための改善が入ったようなので、普通にGC.enableしてOut-of-band GCもしない状態を本番の一部のサーバーで検証したところ、それほどパフォーマンスも劣化せず、かつCPU使用率が1割程度下げられそうな計測結果が得られた。

迷ったら健全な方

そこでインフラ部と相談し、「GC を無効化する運用は健全じゃないと考えています。Ruby の GC の改善がクックパッドにどう影響するのかというのをちゃんとコミュニティに還元するべき」という理由からGC.enableの許可をインフラ部長のmirakuiさんからいただいたので、特に何も起こらなければ来週からGCが有効になる予定。*4 結果は何かの機会にコミュニティに還元されるでしょう。

*1:アセットプリコンパイルにおいて、Sprockets 2だとjsがボトルネックになり、Sprockets 3だとcssがボトルネックになるというのが根拠。なぜ遅いのかは調査中。

*2:独自パッチによる並列化なしの状態での計測

*3:Unicorn::OobGCとかと違ってGC.startしないのでOobGCと呼ぶのを控えている

*4:僕は本番サーバーには触れないので実際の作業はsora_hにお願いしている