Edited at

RailsにおけるCacheの概念と使い方

More than 1 year has passed since last update.


Cache

キャッシュとは、使用頻度の高いデータを高速な記憶装置に蓄えておくことにより、いちいち低速な装置から読み出す無駄を省いて高速化すること。また、その際に使われる高速な記憶装置や、複製されたデータそのもののこと。


RailsにおけるCache


Rails3

Rails3までは以下の3つの代表的な機能を提供していた。


ページキャッシュ

レンダリングされたページのHTMLファイルをまるごとキャッシュする機能。キャッシュ化されたファイルはpublicディレクトリ以下に配置され、静的なファイルとして返す。


アクションキャッシュ

ページキャッシュは極めて高速だが、使える所が限定される。例えばbefore_filterで認証処理するアクションには適用できない。actionキャッシュはページキャッシュと似たような機能だが、before_filterの後に呼び出されるので、認証処理などの処理ができて、ページキャッシュより柔軟な対応ができる。


フラグメントキャッシュ

webページの多くは動的で、複数の部品(フラグメント)に構成される。フラグメントキャッシュは、部品ごとにキャッシングを行いキャッシングストアにデータを保存する。2回目以後のリクエストは部品をキャッシュストアから取り出す。


Rails4

Rails4ではページキャッシュとアクションキャシュを本体から取り除かれ、gem化されました。詳細はactionpack-page_cachingactionpack-action_cachingを参考してください。


フラグメントキャッシュの使い方


show.slim

- cache 'key' do

キャッシュしたい HTML

上記のように、'key' を指定すると、その中身をキャッシュしてくれる。'key' の部分は、省略もできるし、Stringやオブジェクトも指定できる。


skip_digest: と expires_in: オプション


show.slim

- cache 'key', expires_in: 1.minutes, skip_digest: true do

キャッシュしたい HTML



  • expires_in: 1.minutes: 有効期限を1秒


  • skip_digest: true: デフォルトではキャッシュするHTML文を元にdigestを作成して、'key'の付与している。skip_digest: trueを付ける事でdigestをスキップできる。


キーにStringを指定した場合


show.slim

- cache 'key' do

キャッシュしたい HTML

この場合は、Stringのキーに対応した形でシンプルにHTMLがキャッシュされる。内部的に実際には使われるキーにはデフォルトだと中身のHTMLを元に作ったdigestが付与されるため、cacheしたいHTML自体が変更されれば、digestが変更され、自動でキャッシュが更新される。


キーを省略した場合


show.slim

- cache do

キャッシュしたい HTML

上記のように、キーを省略した場合は、ページのurlからキーが自動で作られる。url依存のキーなので、同じページでこの形を複数記述すると、どちらかのキャッシュが上書きされて大変なことになる。


キーにオブジェクトを指定した場合


show.slim

- cache @object do

= @object.text

オブジェクトを指定した場合は、@object.cache_keyがキャッシュのキーとなる。ActiveRecordのオブジェクトの場合、IDや、updated_at を元にキーが作成されるので、オブジェクトのupdated_atが変更されると自動でキャッシュも更新される。


show.slim

- cache @objects do

- @object.each do |object|
= object.text

上記のように配列にした場合は、各オブジェクトに対して cache_key が呼ばれてそれを連結したものがキャッシュのキーになる。よって配列の順番や中身が変更されればキャッシュは更新される。


Russian doll caching(ロシアンドールキャッシング)

以下のように、記事(article)に対して複数のコメント(comment)があるデータ構造の場合、ネストされたフラグメントキャッシュの内側のキャッシュ(comment)が更新されると、外側のキャッシュ(article)も更新してくれる機能。rails 4ならデフォルトで利用可能。


show.slim

- cache @article do

= @article.title
= @article.text

- cache @article.comments do
- @article.comments do |comment|
= comment.text


この場合はモデル側で以下のように、モデル側にtouch: true設定をする必要がある。


comment.rb

class Comment < ActiveRecord::Base

belongs_to :article, touch: true


参考記事