「キャッシュの使いどころ覚書」に関しての考えをまとめました。
目次
キャッシュは特定の場面において劇的な効果をもたらします。負荷軽減や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)
}