「キャッシュの使いどころ覚書」に関しての考えをまとめました。

目次

キャッシュは特定の場面において劇的な効果をもたらします。負荷軽減やUX改善といった明確なメリットがあるため、多くの問題をキャッシュを用いて解決されることがあります。しかしながら、使いどころを誤るとアプリケーションの複雑性が増し、保守や変更が困難になってしまいます。この特徴を比喩して、「キャッシュは麻薬」と呼ばれているそうです。

ではどのタイミングでキャッシュを利用するとよいのか

この答えは簡単ではなく、キャッシュの使いどころは、アプリケーションの特徴や、業務ドメイン、予算といった要因により左右されてしまいます。なかなか一般化できないものだと思います。 とはいえ、ユースケースやアンチパターンを知っておくと、判断基準を持つことができると思います。

自分が見かけたことのある具体的な事例は以下の通りです。

商品情報を入手する

  • アクセスしたタイミングでキャッシュを確認+発行
  • キャッシュ保持期間は、TTLだが、LifeTimeを短くしているため動作上はLRU型のようになるかも。
public function detail($productId)
{
    // 商品IDに紐づくキャッシュインスタンスを作って
    $productCache = new Cache($productId);
    // キャッシュがあったらその戻り値を取得
    if ($productCache->hasCache()) {
        $product = $productCache->getValue();
    } else {
        // なければDBから取得して
        $product = $this->_service->getProductFromDB($productId);
        // キャッシュにセット
        $productCache->setCache($product);
    }
}

ランキング情報を取得する

  • キャッシュの保持期間は、TTL形式
  • ランキングは毎晩バッチでDBを更新+キャッシュに保存
  • バッチは手動でも実行できるようにしている
  • 要件として、さほど即時性が求められない

要件によっては、DBに保存せずキャッシュで管理してもよいかもしれない

public function ranking()
{
    // キャッシュを取得して
    $cache = new RankingCache();
    // キャッシュがあったらその戻り値を取得
    if ($cache->hasCache()) {
        $product = $cache->getValue();
    } else {
        // なければ警告メールを送信して
        $product = $this->sendMail();
        // ランキングを取得して
        $ranking = $this->runRankingBatch();
        //キャッシング
        $cache->setCache($ranking);


    }
}

あなたにおすすめの商品

  • レコメンド系でユーザーごとに固有の商品を表示する
  • 他の例はアプリケーションサーバとDBサーバ間のキャッシュだったが、これはクライアントとアプリケーションサーバー間のキャッシュ
  • そのため他と勝手が違う
  • 本ページはJSでlocalStorageを使っている
  • cacheでも保存できるが、HTTPリクエスト時に送信してしまうため、本要件では不適切
const recommendKey= 'recommendItems'
// ローカルストレージから取得してみる
let products = localstrage.getItem(recommendKey)
// ローカルストレージに存在しなければ
if (!products) {
 // レコメンド商品を取得して
 products = getRecommendProducts()
 // セットする
 localstrage.setItem(recommendKey, products)
}

参考文献

キャッシュを活用するために必要な知識と勘所 - そーだいなるらくがき帳