Redisキャッシュスタンピード対策ガイド:高負荷時にDBを守る設計と実装

Redisキャッシュスタンピード対策ガイド:高負荷時にDBを守る設計と実装 Redis を使っていても、ピークトラフィック時に DB が突然落ちることがあります。原因の多くはキャッシュスタンピードです。人気キーの TTL が同時に切れると、大量リクエストが一斉に DB へ流れ、接続プールが飽和します。 「Redis を入れたのに遅い」「ピーク時だけ 500 が増える」という現象は、このパターンで説明できることが非常に多いです。 本記事では、キャッシュスタンピードを実運用で防ぐために、設計原則・実装パターン・監視方法を順に解説します。 1. キャッシュスタンピードとは何か 典型シナリオ: 商品ランキング API が ranking:daily を Redis に 300 秒で保存 300 秒後、人気時間帯にキー期限切れ 同時に 1000 リクエストが miss 1000 回 DB 集計が走ってレイテンシ急増 このとき Redis 自体は正常でも、背後の DB が壊れます。つまり、問題はキャッシュ障害ではなく「再生成の同時実行制御」です。 2. 防御の基本は三層構え スタンピード対策は単一施策では不十分です。次の三層を組み合わせると安定します。 同時再生成の抑制(singleflight / 分散ロック) 期限切れの分散(TTL ジッター) 期限切れ後の挙動制御(stale-while-revalidate) 3. パターン1: singleflight で同時再生成を止める 同一キーの miss が同時発生しても、1 リクエストだけ再生成し、他は待つ設計です。 TypeScript 例: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 const inflight = new Map<string, Promise<string>>(); async function getOrCompute(key: string, ttlSec: number, compute: () => Promise<string>) { const cached = await redis.get(key); if (cached) return cached; if (!inflight.has(key)) { const p = (async () => { try { const value = await compute(); await redis.set(key, value, { EX: ttlSec }); return value; } finally { inflight.delete(key); } })(); inflight.set(key, p); } return await inflight.get(key)!; } 単一プロセスではこれで十分ですが、複数インスタンス構成では分散ロックも必要です。 ...

March 2, 2026 · 2 min · AI2CORE 編集部