ストーリー
高橋アーキテクトが最後の課題を出した。
総合演習の概要
5つのパートで、Month 6の全スキルを実践します。
| パート | テーマ | 時間 | 使うスキル |
|---|---|---|---|
| Part 1 | 現状分析と目標設定 | 15分 | パフォーマンスバジェット、計測 |
| Part 2 | キャッシュ戦略の設計 | 20分 | キャッシュ設計、無効化 |
| Part 3 | スケーリング計画 | 20分 | 水平/垂直スケーリング、非同期処理 |
| Part 4 | 負荷テスト計画 | 20分 | k6、シナリオ設計 |
| Part 5 | フロントエンド最適化 | 15分 | Core Web Vitals、CDN |
Part 1: 現状分析と目標設定(15分)
現状のシステム情報
インフラ:
App Server: 3台(4vCPU, 16GB RAM)
Database: PostgreSQL 1台(8vCPU, 32GB RAM)+ Read Replica 1台
Cache: Redis 1台(4GB RAM)
CDN: なし
パフォーマンス指標(通常時 1000 RPS):
API p50: 80ms, p95: 200ms, p99: 450ms
LCP: 3.2秒
CLS: 0.22
エラー率: 0.05%
キャッシュヒット率: 60%
DB CPU: 45%, App CPU: 35%
ストレステスト結果(2000 RPS時):
API p50: 250ms, p95: 800ms, p99: 3200ms
エラー率: 2.5%
DB CPU: 92%, App CPU: 65%
Redis メモリ: 85%
課題
セール時10000 RPSに対応するための目標値とギャップを分析してください。
解答例
=== 目標値(SLO) ===
API p50: 100ms以下
API p95: 300ms以下
API p99: 500ms以下
LCP: 2.5秒以下
CLS: 0.1以下
エラー率: 0.1%以下
キャッシュヒット率: 95%以上
=== ギャップ分析 ===
1. DB がボトルネック
現状: 1000RPSでCPU 45% → 2000RPSでCPU 92%
10000RPSでは完全に飽和する
対策: Read Replica追加 + キャッシュヒット率向上
2. キャッシュヒット率が低い
現状: 60% → 40%のリクエストがDBに到達
目標: 95% → 5%のみDBに到達
対策: TTL見直し + キャッシュ対象の拡大
3. App Server が不足
現状: 3台で1000RPS → 10000RPSでは最低30台が必要
対策: オートスケーリング + ステートレス確認
4. Redisメモリ不足
現状: 1000RPSで85% → キャッシュ増加でOOM
対策: Redis Cluster化 + メモリ増強
5. CDN未導入
静的アセットがオリジンから配信されている
対策: CDN導入で静的アセットのRPSをオフロード
6. フロントエンドのCWV未達
LCP 3.2秒, CLS 0.22 → 目標未達
対策: 画像最適化 + width/height指定
Part 2: キャッシュ戦略の設計(20分)
キャッシュヒット率を60%から95%に向上させるための戦略を設計してください。
対象データと現状
| データ | 現状TTL | ヒット率 | RPS割合 |
|---|---|---|---|
| 商品一覧 | 5分 | 70% | 30% |
| 商品詳細 | 30分 | 80% | 25% |
| 検索結果 | なし | 0% | 15% |
| カート | なし | 0% | 10% |
| ランキング | 1時間 | 90% | 10% |
| セッション | 30分 | 95% | 10% |
解答例
// 改善後のキャッシュ設計
const improvedCacheStrategy = {
// 商品一覧: TTL延長 + イベント無効化
productList: {
beforeTTL: 300, // 5分
afterTTL: 600, // 10分に延長
invalidation: 'event-based', // 商品更新時にイベントで無効化
expectedHitRate: 90, // 70% → 90%
},
// 商品詳細: 既に良好、微調整
productDetail: {
beforeTTL: 1800,
afterTTL: 1800, // 維持
invalidation: 'event-based',
expectedHitRate: 90, // 80% → 90%
},
// 検索結果: 新規キャッシュ導入
searchResults: {
beforeTTL: null, // キャッシュなし
afterTTL: 120, // 2分のキャッシュ導入
cacheKey: 'search:{query}:{page}:{sort}',
expectedHitRate: 70, // 0% → 70%
},
// カート: Redisセッション内にキャッシュ
cart: {
beforeTTL: null,
afterTTL: 1800, // Write-Through
strategy: 'write-through',
expectedHitRate: 85, // 0% → 85%
},
// ランキング: 既に良好、維持
ranking: {
beforeTTL: 3600,
afterTTL: 3600,
expectedHitRate: 95, // 90% → 95%
},
// セッション: 維持
session: {
beforeTTL: 1800,
afterTTL: 1800,
expectedHitRate: 95,
},
};
// 全体のキャッシュヒット率の計算
// = Σ(各データのヒット率 × RPS割合)
// = 90*0.30 + 90*0.25 + 70*0.15 + 85*0.10 + 95*0.10 + 95*0.10
// = 27 + 22.5 + 10.5 + 8.5 + 9.5 + 9.5
// = 87.5%
// さらにCDNでの静的アセットキャッシュを考慮すると
// 全体で約92-95%のキャッシュヒット率が期待できる
Thundering Herd対策:
- セール開始前にランキング・人気商品のキャッシュをウォームアップ
- Singleflightパターンで同時DB問い合わせを制限
- TTLにジッター(+0-60秒)を追加して同時期限切れを回避
Part 3: スケーリング計画(20分)
10000 RPSに対応するためのスケーリング計画を策定してください。
解答例
=== インフラスケーリング計画 ===
1. App Server
現状: 3台(4vCPU)→ 1000 RPS対応
目標: 最大30台 → 10000 RPS対応
戦略: オートスケーリング
- 通常時: 5台
- セール前日23:00: 20台にスケールアウト(事前スケーリング)
- セール中: CPU 60%超で+3台、30%以下で-1台
- 最大: 30台
前提: ステートレス確認済み(JWT認証 + Redis Session)
2. Database
現状: Primary 1台 + Replica 1台
目標: Primary 1台 + Replica 3台 + スペック増強
戦略:
- Read Replica: 1台 → 3台(読み取り3倍化)
- Primary: 8vCPU → 16vCPU(垂直スケーリング)
- コネクションプール: max=20 → max=100
3. Redis
現状: 1台(4GB)
目標: Redis Cluster 3ノード(各8GB = 計24GB)
戦略:
- メモリ増強でキャッシュ容量確保
- クラスタリングで負荷分散
4. CDN
現状: なし
目標: CloudFront導入
効果: 静的アセット(画像、CSS、JS)のRPSをオフロード
→ オリジンへのRPSを50%削減
5. メッセージキュー
現状: なし
目標: SQS導入
対象: メール送信、PDF生成、分析イベント
Worker: 1-10台(キュー深さに応じてスケーリング)
=== コスト見積もり ===
通常時: $2,000/月(App 5台 + DB 2台 + Redis 1台)
セール時: $8,000/月(App 20台 + DB 4台 + Redis 3台 + CDN + SQS)
Part 4: 負荷テスト計画(20分)
セール前に実施する負荷テストの計画を立ててください。
解答例
=== 負荷テスト実施計画 ===
Phase 1: ベースラインテスト(Day 1)
種類: ロードテスト
負荷: 1000 RPS × 10分
目的: 改善前のベースラインを記録
環境: ステージング(本番同等構成)
Phase 2: スケーリング確認テスト(Day 7)
種類: ストレステスト
負荷: 1000 → 5000 → 10000 → 15000 RPS(段階的)
目的: 飽和点の特定、オートスケーリングの動作確認
観察項目:
- 各段階でのレイテンシ変化
- オートスケーリングの起動時間
- DBレプリカの負荷分散状況
Phase 3: セールシミュレーション(Day 14)
種類: スパイクテスト
負荷: 1000 RPS → 10000 RPS(1分で急増)→ 10000 RPS維持(30分)→ 1000 RPS
シナリオ:
- 閲覧: 60%(商品一覧 + 詳細)
- 検索: 20%
- 購入: 20%(セール時は購入比率が高い)
目的: セール開始時のスパイクに耐えられるか確認
Phase 4: 耐久テスト(Day 21)
種類: ソークテスト
負荷: 5000 RPS × 4時間
目的: メモリリーク、コネクションリーク、Redis OOMの検出
Phase 5: 最終確認テスト(Day 25)
種類: セールシミュレーション再実行
目的: 全ての修正が反映された状態での最終確認
=== 合格基準 ===
p95: 300ms以下
p99: 500ms以下
エラー率: 0.1%以下
スループット: 10000 RPS以上
オートスケーリング: 5分以内にスケールアウト完了
Part 5: フロントエンド最適化(15分)
セール時のフロントエンドパフォーマンスを確保するための施策をまとめてください。
解答例
=== フロントエンド最適化施策 ===
1. セールページの事前最適化
- セールバナー画像: AVIF/WebP + preload
- セールページのHTMLをCDNにプリキャッシュ
- Critical CSS のインライン化
2. バンドル最適化
- セールに不要なコンポーネントをLazy Loading化
- 初期バンドルを300KB以下に維持
- Service Workerで静的アセットをプリキャッシュ
3. CDN設定
- セール画像を事前にCDNにプッシュ(オリジンプッシュ)
- エッジでの画像最適化有効化(リサイズ + フォーマット変換)
- APIレスポンスの短期キャッシュ(商品情報: 1分)
4. CWV目標の達成
- LCP: 2.5秒以下(Hero画像のpreload + CDN)
- INP: 200ms以下(重い処理のWeb Worker化)
- CLS: 0.1以下(全画像にwidth/height指定済み)
5. 障害時のフォールバック
- CDN障害: オリジンに直接接続
- API障害: 静的なキャッシュページを表示
- 決済障害: エラーメッセージ + リトライボタン
達成度チェック
| パート | テーマ | 完了 |
|---|---|---|
| Part 1 | 現状分析と目標設定 | [ ] |
| Part 2 | キャッシュ戦略 | [ ] |
| Part 3 | スケーリング計画 | [ ] |
| Part 4 | 負荷テスト計画 | [ ] |
| Part 5 | フロントエンド最適化 | [ ] |
まとめ
| ポイント | 内容 |
|---|---|
| 現状分析 | データに基づいてボトルネックを特定 |
| キャッシュ | ヒット率60% → 95%で DBへのRPSを大幅削減 |
| スケーリング | App水平 + DB垂直/Read Replica + Redis Cluster |
| 負荷テスト | 段階的にテスト種類を変えて網羅的に検証 |
| フロントエンド | CDN + 画像最適化 + バンドル最適化でCWV達成 |
チェックリスト
- 現状のメトリクスからボトルネックを特定できた
- キャッシュ戦略でヒット率向上の計画を立てられた
- 10倍のトラフィックに対応するスケーリング計画を策定できた
- 段階的な負荷テスト計画を立案できた
- フロントエンドのCWV達成施策を列挙できた
次のステップへ
お疲れさまでした。全ての知識を統合した総合的な設計力が身についたはずです。
最後に、卒業クイズに挑戦しましょう。
推定所要時間: 90分