キャッシュ
頻繁にアクセスされるデータを高速なストレージに保存し、読み取り性能を向上させる手法
パフォーマンス設計
キャッシュとは
キャッシュは、頻繁にアクセスされるデータを高速なストレージ (メモリ) に保存し、読み取り性能を向上させる手法である。「コンピュータサイエンスで難しいことは 2 つだけ。キャッシュの無効化と命名だ」(Phil Karlton) という格言があるほど、正しく運用するのは難しい。
キャッシュの階層
ブラウザキャッシュ (最速、ユーザーごと)
↓ ミス
CDN キャッシュ (CloudFront、エッジロケーション)
↓ ミス
アプリケーションキャッシュ (ElastiCache / Redis)
↓ ミス
データベース (DynamoDB / RDS)
キャッシュ戦略
| 戦略 | 読み取り | 書き込み | 用途 |
|---|---|---|---|
| Cache-Aside | キャッシュミス時に DB から取得してキャッシュ | DB に書き込み、キャッシュを無効化 | 汎用 |
| Read-Through | キャッシュが自動的に DB から取得 | - | DAX |
| Write-Through | - | キャッシュと DB に同時書き込み | 一貫性重視 |
| Write-Behind | - | キャッシュに書き込み、非同期で DB に反映 | 書き込み性能重視 |
Cache-Aside の実装
async function getUser(id: string): Promise<User> {
// 1. キャッシュを確認
const cached = await redis.get(`user:${id}`);
if (cached) return JSON.parse(cached);
// 2. キャッシュミス → DB から取得
const user = await db.get({ TableName: 'users', Key: { id } });
// 3. キャッシュに保存 (TTL 1時間)
await redis.set(`user:${id}`, JSON.stringify(user.Item), 'EX', 3600);
return user.Item as User;
}
キャッシュの無効化
| 方法 | 説明 | トレードオフ |
|---|---|---|
| TTL (Time-To-Live) | 一定時間後に自動削除 | 古いデータが TTL まで残る |
| 明示的削除 | 更新時にキャッシュを削除 | 削除漏れのリスク |
| イベント駆動 | DynamoDB Streams で変更を検知して削除 | 実装が複雑 |
AWS でのキャッシュ
| レイヤー | サービス | TTL の目安 |
|---|---|---|
| CDN | CloudFront | 静的ファイル: 1 日、API: 数秒〜数分 |
| アプリケーション | ElastiCache (Redis) | 数分〜数時間 |
| DB | DynamoDB DAX | 数分 |
| DNS | Route 53 | 60〜300 秒 |
よくある失敗
- キャッシュの TTL が長すぎて古いデータが表示される
- キャッシュの無効化漏れで、更新が反映されない
- キャッシュスタンピード: TTL 切れ時に大量のリクエストが DB に殺到
現場での応用を知るには関連書籍も役立つ。