キャッシュってなんだ!わかんないから調べてみた

Pocket
LINEで送る

こんにちは!
新人の川原です。

暑くなってきましたが、いかがお過ごしでしょうか?
弊社ではクーラーをつけたり切ったりしながら温度調節する毎日です。
空調は体調がおかしくなるのであまり好きじゃないのですが、つけないと暑いジレンマ・・・
大きい扇風機が欲しい・・・(難しいらしいですが)
さて、今回はrailsのキャッシュについてまとめてみました。

なぜやったのか

サーバーキャッシュ、ブラウザキャッシュ、アプリ内のキャッシュ・・・
どれがなんだかフワッとはわかるけれども厳密にどういうものがあるのかはわからない。

どこから何が違うのか理解したくて今回はキャッシュを調べてみることにしました。
一番整理できていなかったのがrailsのキャッシュについてだったので書くことにしました。

Railsのキャッシュについて

Railsのキャッシュは公式ドキュメントから持ってくると以下となります。

ページキャッシュ
アクションキャッシュ
フラグメントキャッシュ
ロシアンドールキャッシュ
低レベルキャッシュ
SQLキャッシュ

はい。よくわからないですね。
特に上4つ。

というわけで、わかりやすくするために大きく分けると以下のようになっています。(自分なりの解釈なので少しニュアンスが異なるかもです)
・ビューで使うキャッシュ
・モデル・コントローラで使うキャッシュ
・SQLキャッシュ

この分類に先ほどの公式ドキュメントを合わせるとこんな感じに

・ビューキャッシュ

ページキャッシュ
アクションキャッシュ
フラグメントキャッシュ
コレクションキャッシュ
ロシアンドールキャッシュ

・モデル・コントローラで使うキャッシュ

低レベルキャッシュ

・SQLキャッシュ

SQLキャッシュ
機能について
一つずつ説明していきます。
説明を簡単にするため順番前後します。

⭐︎フラグメントキャッシュ

動的なwebアプリを作る際に異なるコンポーネントからページが生成されます。
これらのパーツ毎にキャッシュを設定できるのがフラグメントキャッシュです。

例えばページ内に天気を表示する部分があったとしましょう。
天候は1日ごとに変わりますし、1日の中でも変化する項目だと思います。
こういう時にフラグメントキャッシュが働きます。

<% @weather.each do |weather| %>
  <% cache weather do %>
    <%= render weather %>
  <% end %>
<% end %>

天候が変わるまではキャッシュを保持し、天候が変わればキャッシュを削除し新たな情報を表示してくれます。

キャッシュ自体はキー、バリューの形で保存されます。

キーはユニークにするためupdated_atのtimestampが使用されるようです。

⭐︎コレクションキャッシュ

フラグメントキャッシュの一部のようなものなんですが、
renderヘルパーを使う際にcollectionを指定するとフラグメントキャッシュをしてくれます

<%= render partial: "partials/weather', collection: @weather, cached: true %>

 

⭐︎ページキャッシュ&アクションキャッシュ

この2つは詳しくは説明しません。

簡単に言うとページ全体をキャッシュしてくれる機能です。
フラグメントキャッシュがあれば、あまり利用シーンはないですよね。

だからなのかrails4からはgem化され、railsの機能から外れています。

⭐︎ロシアンドールキャッシュ

フラグメントキャッシュ内でさらにキャッシュしたい場合等で仕様出来る。
名前からわかるがマトリョーシカをイメージしての命名らしい。お茶目。

設定は下記のように

<% cache weather do %>
  <%= render weather.temperatures %>
<% end %>
<% cache tmeperature do %>
  <%= render temperature %>
<% end %>

気温が更新されると、天気のキャッシュは削除されずに気温だけ変わります。

気温が更新時に天気のキャッシュを消したい場合は下記のようにする必要があります。

class Weather < ApplicationRecord
  has_many :temperatures
end
class Weather < ApplicationRecord
  has_many :temperatures
end

 

 

 

⭐︎低レベルキャッシュ

特定の値やクエリのキャッシュなどをキャッシュしたい時などに使えるキャッシュです。
設定方法は以下のようにRails.cache.fetchにキーを指定することでできます。でできます。
(コードはrailsガイドからお借りしました。)

 

class Product < ApplicationRecord
  def competing_price
    Rails.cache.fetch("#{cache_key}/competing_price", expires_in: 12.hours) do
      Competitor::API.find_price(id)
    end
  end
end

⭐︎SQLキャッシュ

設定不要で、自動的にやってくれる機能です

class ProductsController < ApplicationController
   def index
     # 検索クエリの実行
     @products = Product.all
     ...
     # 同じクエリの再実行
     @products = Product.all
  end
end

こういう時はデータベースにアクセスしないようになっています。
(@product使えばいいのでこんな書き方することあるのか不明ですが)

アクションが終了する時にキャッシュは破棄されるので、もっと持続させたい場合は0レベルキャッシュを使いましょう

キャッシュストアについて
キャッシュの保存場所のことです。
任意の箇所にキャッシュを保存することができます。

簡単に
デフォルトの設定とキャッシュを保存しない方法について説明します

デフォルトの設定
ActiveSupport::Cache::MemCacheStore

memcachedサーバーにアプリケーションのキャッシュを一元化保存されているそうです。
memcachedについては長くなるので各自で調べてください。
こちらのmixiのブログさんがわかりやすかったです。

設定は以下

config.cache_store = :mem_cache_store, "cache-1.example.com", "cache-2.example.com"

キャッシュを保存しない方法

開発環境やtest環境などでキャッシュがあることで作業がしにくいことがあるかと思います
そういったときに書きの設定にするとキャッシュを保存しなくなります。

development環境とtest環境のみ設定可能です

config.cache_store = :null_store

以上です。
いかがでしたでしょうか?
まだまだ知識が足りないので、初歩的なことかもしれませんがどんどんまとめていきたいと思っています。

Pocket
LINEで送る