asin: 4797363827
title: “[Rails高速化] ページキャッシュ、N+1対策、SQLチューニング”
category: Rails
🐯 tags: [Rails, Ruby, Gem]
『Cookpadではユーザーへのレスポンスタイム 200ms/reqを目標にしている』に感銘を受けて書き始めたこの記事ですが、『パフォーマンス・チューニングやオススメGem in 「Rails勉強会@東京 第88回」』でいろいろ教えてもらったり、最近関わっているサイトのリニュアールで試行錯誤したので、忘備録も兼ねて記事をアップデートします!
🚕 目次
(1) N+1問題の対策
(2) Railsのキャッシュについて
(3) 開発中ならrack_mini_profiler
(4) 運用中なら断然NewRelicがおすすめ
(5) mysqlの簡単チューニング
🚌 (1) N + 1問題の対策Gem Bullet
Bulletの導入手順
RailsのActive Record(findやwhere)は便利ですが、DB(SQL)の側から見ると非効率的なクエリを発生させることがあるようです。これを監視して警告を出してくれることで有名なGemが『Bullet』です。
まずは、bulletをインストールします。Gemfile
に以下を追記してbundle install
を実行。
group :development do |
続いてconfig/environments/development.rb
に以下を追記。
AppName::Application.configure do |
これでブラウザで開発サイトを普通に閲覧していると、N+1問題が発生するページではアラートを出してくれます。
複数のテーブルを含むincludesについて
Bulletでは関連テーブルを呼び出すようなSQLを検知した場合に、複数のテーブルを含むincludes
をするようにアラートが出ます。たとえば、ブログ(Blog)に記事(Articles)があり記事に複数の画像(Images)があるようなモデルを考えます。
Blog => Articles => Images
この場合には、Active Recordで次のようなコードを書けば複数テーブルを含むincludes
を指定できます。
Blog.includes(articles: [:images]) |
頭のなかだけで考えただけですので、間違っている可能性もありますが、このようにハッシュ&Array&Symbolでうまく呼び出してあげる必要があります。こちらの記事『【Ruby On Rails3】 複数のテーブルのincludesを書く! | approad』を参考にさせていただき、うまく組むことができました!
🐰 (2) Railsのキャッシュについて
フラグメントキャッシュ(RussianDollCaching)
Rails 4になって、メインのキャッシュ機能は『フラグメントキャッシュ(RussianDollCaching)』になったようです。
フラグメントキャッシュの詳細な説明は、『Rils4で Russian Doll Caching を楽しむためのまとめ [俺の備忘録]』がわかりやすくてお勧めです!
ちなみに、恥ずかしながら最近フラグメントキャッシュを使うようになりましたが、cache model
でid-updated_at
という情報を付加してくれます。(modelに変更があったら自動的にキャッシュがアップデートされます)かなり気に入っています^^
ページキャッシュについて
Rails 4からは、ページキャッシュは別のgem『rails/actionpack-page_caching』として提供されるようになったようです。
こちらの記事『Page caching with Rails 4』は英語ですが、シンプルでわかりやすい説明です。ページキャッシュはRailsを介さずにApacheと直接やりとりができるため、レスポンスが高速になるので、もし使いやすいサイトであれば積極的にトライしてみるのもありだと思います!
🎃 (3) 開発中ならrack_mini_profiler
現状、Railsのプロファイラで一番メジャーなのは、『MiniProfiler/rack-mini-profiler』です。
ViewのレンダリングやActive Recordの問い合わせにかかっている時間などを計測して教えてくれます。
導入方法もいたって簡単です! Gemfileに次のコードを追加して、コマンドラインでbundle install
を実行。
gem 'rack-mini-profiler' |
あとは、ブラウザで開発サイトを普通に閲覧していると、小さく速度を計測して表示してくれます。ドリルダウンで詳細な問い合わせ内容もすぐにわかってボトルネックの部分を調べることができます!
🐹 (4) 運用中なら断然NewRelicがお勧め
実運用中のサイトのチェックであればNewRelicがやはりお勧めです。上のサイトは去年開催された『New Relic Nightを開催しました。(動画&スライド)』の内容です。運用ノウハウのつまったスライドが多数あります。
以前『Rails勉強会@東京 第88回』に参加させていただいた際にも次のようなメリットがあるというのを教えていただきました!
* アプリケーションの監視に最適なツール * アクション => メソッド、sqlが遅いまでチェックできる * アクションをひとつひとつチェック => 定義・構造がおかしいか探す => レンダリングの改善 * サイト全体平均より、重要なページを計測して改善をすべき * js側のチェックも出来る
😸 (5) MySQLの簡単チューニング
Railsで作ったサービスの速度改善方法について教えて下さい - QA@ITの中にあるMySQLの簡単なチューニングをやってみたところ、僕の環境でも体感で速度が改善しました。
まず、vim my.cnf
の中の次の設定を変更します。
innodb_buffer_pool_size = # サーバのメモリ70〜80% |
次にMySQLの
innodb_log_file_sizeを変更するために、MySQLにログインして次のコマンドを実行します。
mysql> SET GLOBAL innodb_fast_shutdown=0; |
次にMySQLをストップします。
/etc/init.d/mysqld stop |
そしてトランザクションファイルを削除(もしくは移動)。
rm /var/lib/mysql/ib_logfile0 |
MySQLを起動します。
トランザクションログファイルが作成されていれば成功です。
🐮 参考リンク
N+1問題などを監視してパフォーマンスを改善するRailsプラグインBullet|WEBデザイン Tips
Railsの画面生成を10倍高速化する方法 - 世界線航跡蔵
MySQLの「innodb_buffer_pool_size」と「innodb_log_file_size」の設定 – FlatLabs
🐡 変更来歴
13/04/17 10:00 Bulletの仕様変更により、development.rbの設定を変更
13/05/20 17:35 MySQLの簡単チューニングを追加
14/01/26 19:05試行錯誤した結果にもとづいていくつか書き直し