Rails3 まで
-
ページキャシュ(ページ全体をキャッシュ)
ページのレンダリング結果を静的な HTMLファイルとしてファイルシステムに保存する機能。HTMLファイルは publicディレクトリ以下に配置され、Webサーバ(Nginxなど)から直接返すことができる。リクエストパラメータ(条件付き GET リクエスト)が付与される場合は避けた方が良い。
-
アクションキャッシュ(アクション単位でキャッシュ)
ページキャッシュと同じく、ページ全体をキャッシュする機能。柔軟な制御をしたい場合はアクションキャッシュを用いる。(非ログインユーザのみに対してページキャッシュしたいなど)アクションキャシュは、Webサーバで直接返さず、2回目以降のアクセスでも Rails で処理する。その分負荷がかかるが、柔軟な制御ができる。また、アクションキャシュの保存は設定した Railsのキャッシュストア(ActionController::Base.cache_store)が用いられる。
-
フラグメントキャッシュ(ページの一部をキャシュ)
HTMLを部分的にキャッシュする機能。多くのページで共通するHTMLがある場合などに有効的。1度目のレンダリング時にHTML文字列としてキャッシュストアに保存され、2度目以降のレンダリングでは、キャッシュストアに保存されたそのHTMLが使われる。
上記の3つが代表的なキャッシュ機能としてあった。
Rails4
- フラグメントキャッシュ(ページの一部をキャシュ)
ページキャッシュと、アクションキャシュは廃止され、フラグメントキャシュのみ使える。
Russian Doll Caching、cache_digests、fragmen cache などと呼ばれるものは、Rails3 までのフラグメントキャシュと指し示すものとすべて同じ。
Rails4 で内部的に使われているgemが、従来のRailsにおける fragment cache を進化させた cache_digests であり、cache_digestsの仕組みに対する愛称が Russian Doll Caching である。
Rails3 までの違いは、複数のフラグメントキャッシュを入れ子にしている場合に、内側のコンテンツの更新に連動して、外側のフラグメントキャッシュのキーが自動的に変更される。(マトリョーシカってそういうことか。)
キャッシュを使う(Russian Doll Caching)
ビューの中に、下記のように記述する
<% cache do -%>
キャッシュしたい内容
<% end -%
内側のモデル(belongs_to で touch: trueオプションを加える)を修正する。
これで、内側のモデルが更新された時に、外側も更新(updated_at)されるようになりキャッシュも更新される。
キャッシュキー
キャッシュのキーは、デフォルトでキャッシュメソッドが呼び出されたURLから生成される。
views/<domain>/<controller>/<action>/<MD5>
明示的に指定することもできるけど、デフォルトでモデルのインスタンスをキャッシュのキーに指定されて、キーの中にupdated_at
を含むので、モデルが更新されたらキャッシュも更新されて便利っぽい。
キャッシュストア
キャッシュストアには、標準(ActiveSupport)でファイルシステム、メモリ、Memcached がある。用途に合わせて使い分ける必要があるが、 スケールアウト(キャッシュの一元化、ヒット率)を考えると多くの場合 Memcached をキャッシュストアとして使うと良さそう。
アクションキャッシュ、ページキャッシュを使いたいという場合
- rails/actionpack-action_caching : https://github.com/rails/actionpack-action_caching
- rails/actionpack-page_caching : https://github.com/rails/actionpack-page_caching
分離された gem を用いることで使うことができる。
(DHH の思想で Rails のコアからは廃止されたので、非推奨?)
ページキャッシュなどは、 Nginx や Varnish などが担う役割とのことなので、次回は Varnish もしくは Nginx を用いてページキャッシュを実現してみようと思うます。
引用・参考
以下の書籍、記事から多く引用・参考にさせていただきました。
スライドや図、サンプルコードなどもあってとてもわかりやすいです。
- WEB+DB PRESS Vol.70|技術評論社 : http://gihyo.jp/magazine/wdpress/archive/2012/vol70
- Rails アプリケーションのパフォーマンスについて RubyKaigi 2013 で発表しました - クックパッド開発者ブログ : http://techlife.cookpad.com/entry/2013/06/07/rubykaigi-high-performance-rails/
- Rils4で Russian Doll Caching を楽しむためのまとめ [俺の備忘録] : http://o.inchiki.jp/obbr/201
- [Rails 高速化] ページキャッシュ、N+1対策、SQLチューニング - 酒と泪とRubyとRailsと : http://morizyun.github.io/blog/speed-up-rails-bullet/
- Railsでページキャッシュ( page caching )を使うべきでない理由 - masa_wの日記 : http://masa-w.hatenablog.com/entry/2014/02/21/180614
- 【Rails 高速化】ペパボのフリマアプリ「kiteco(キテコ)」の API を高速化したときのことを詳しく書いてみた - 彼女からは、おいちゃんと呼ばれています : http://blog.inouetakuya.info/entry/2014/02/08/221438
- How key-based cache expiration works by David of Basecamp : https://signalvnoise.com/posts/3113-how-key-based-cache-expiration-works
- ASCIIcasts - “Episode 387 - Cache Digests” : http://ja.asciicasts.com/episodes/387-cache-digests
- Caching Strategies for Rails | Heroku Dev Center : https://devcenter.heroku.com/articles/caching-strategies