はじめに
キャッシュについてザックリ理解することを目的に書いています。
キャッシュの目的
キャッシュはデータを高速に取得することを目的としており、計算やデータベースの問い合わせなどのコストのかかる処理を減らすことにあります。特に同じデータを複数回取得するとき、キャッシュを利用することでリソースの消費を抑えられます。
大前提、データベースから情報を持ってきたり、計算したり、Webページを生成したりするのには多かれ少なかれ時間がかかります。
高速化は一度取得したデータを一時的に保存し、次回のリクエスト時に再利用することによって実現します。
キャッシュの種類
キャッシュにはブラウザキャッシュやサーバーキャッシュなど色々と種類があります。
ブラウザキャッシュとは、訪問済みのWebサイトのHTML、CSSなどの情報をクライアント側に保存する機能のことです。
キャッシュのストレージ(保存場所)にもいくつか種類があり、
- メモリキャッシュ(インスタンス変数など)
- 外部キャッシュシステム
- ディスクキャッシュ
- データベースキャッシュ
などがあります。
キャッシュの弊害
キャッシュはデータ取得を高速にしてくれるメリットがありますが、更新したはずの情報が反映されていない! というときは、クライアント側に保存された古いキャッシュが悪さをしている可能性があります。
いくら高速になるからと言っても、ずっと古い情報にアクセスさせ続けてしまうのは、たまったもんじゃないですね。
Web開発者は、キャッシュが長期間保存されないようにHTTPヘッダーやクエリパラメータを設定したり、保存期間を設けるなどして適切にキャッシュを管理する必要があります。
いったんまとめ
色々種類があるんだなぁという感じですが、一先ず
キャッシュはデータの取得を高速にするための仕組みです!
キャッシュの仕組みをイメージする
今回はローカルメモリキャッシュ(アプリケーション単位でのキャッシュ)を使って、キャッシュの仕組みのイメージをつけます。
class CacheExample
def initialize
@cache = nil
end
def calculation
# ここで重い計算を行う
print "計算中..."
42 # 計算結果(今回は単純に 42 を返す)
end
def result
# キャッシュされていない場合に計算を実行し、その結果をキャッシュ
@cache ||= calculation
end
end
cache_example = CacheExample.new
puts cache_example.result # 計算中... 42 が表示され、結果がキャッシュされる
puts cache_example.result # 計算は行わず、キャッシュされた値 42 が表示される
another = CacheExample.new # 一応他のインスタンスも作成
puts another.result # 計算中... 42 が表示され、結果がキャッシュされる
puts another.result # 計算は行わず、キャッシュされた値 42 が表示される
肝はこの部分ですね。
@cache ||= calculation
キャッシュがあるならそれを出す、ないなら計算!
さいごに
僕なりの解釈
キャッシュについて調べてるうちにバイト時代を思い出したので、上手いか下手かはさておき、たとえ話をします。(画像は生成AIに作ってもらいました)
バイト時代の話ですが、普通の注文から提供までの流れは
レジに来る→注文をとる→お会計→作成する→提供する
ですが、毎回同じ注文をするお客さん、つまり常連さんも結構いました。
正直、毎回常連さんに丁寧に注文を聞くのは無駄です。なので常連さんには
レジに来る→お会計&作成&提供
みたいな対応が好ましいですよね。
圧倒的に時短になりますし、お客さんとしても待つ時間が少なくて嬉しい! って感じです。
ただ一応、新作が出来た時には、とりあえず注文を聞いたりします。常連さんも毎回当たり前のように「いつもの」を出されたら新作試せないですしね。
僕たちの小さな親切のせいで、お客さんが本当に欲しいものを提供できないのは本末転倒です。
こんな感じで、知っているものはすぐに出してあげる仕組みや、古い情報が悪さをする可能性があることがキャッシュに近いなと思いました。
最後までお読みいただきありがとうございました!!
参考文献