メインコンテンツまでスキップ

Well-Architected: 大量データの設計パターン

大量データを扱うワークロードに焦点を当て、AWS Well-Architected Frameworkの各柱を深掘りします。「なぜ小規模と同じ設計では破綻するのか」を出発点に、段階的に対策を導入する方法を学びます。


所要時間

約70分

学べること

  • 大量データで「何が変わるか」— 小規模では問題にならない設計がなぜ破綻するか
  • データ特性に基づく分類と、ワークロードに応じたサービス選択の判断基準
  • 各設計パターンのメリットだけでなく、導入で引き受けるトレードオフ
  • データ量の成長に合わせた段階的な対策導入の進め方
  • 各Phase(小規模〜大規模)の具体的なAWSコストイメージと最適化手法
  • IDサービスでの統合アーキテクチャ

前提知識

  • Well-Architected Frameworkの6つの柱の基本理解
  • AWSの主要データストアサービス(RDS、S3、DynamoDB等)の基礎知識

目次

  1. 大量データで何が変わるか
  2. データ特性の分類
  3. アプリケーションとインフラの責務
  4. パフォーマンス効率の柱
  5. 信頼性の柱
  6. コスト最適化の柱
  7. セキュリティの柱
  8. 運用上の優秀性の柱
  9. IDサービスの統合アーキテクチャ
  10. 段階的な導入パス
  11. アンチパターン
  12. まとめ

大量データで何が変わるか

小規模なシステムでは問題にならない設計が、データ量の増加とともに破綻します。「大量データ」は単なる数字の違いではなく、設計の前提そのものが変わる質的な変化です。

どこから「大量」なのか

明確な閾値はありませんが、以下の兆候が現れ始めたら設計の見直しが必要です。

兆候具体的な数値目安何が起きるか
DBの応答が遅くなるテーブル行数が数千万行を超えるフルスキャンの所要時間が秒単位に
ストレージコストが無視できなくなる月間のS3/RDS料金が数万円を超える階層化しないと年間で桁が変わる
バックアップ/リストアに時間がかかるDBサイズが100GB超スナップショットの復元に30分以上
ログの検索が実用的でなくなる1日あたり数百万イベントCloudWatch Logsだけでは検索が遅い
書き込みがボトルネックになる秒間数百〜数千の書き込み単一DBのWriter限界に近づく
コネクションが枯渇するアプリケーションインスタンスが50台超DB最大接続数に到達

小規模と大規模で何が違うか

小規模(〜数百万行、〜数十GB):

アプリ ──→ 単一DB ──→ ログファイル

- 1つのDBで全データを管理できる
- SELECT * でも現実的な時間で返る
- ログはファイルに書いて必要なときにgrepで十分
- バックアップは深夜に取れば問題ない
- コストは月額数千円〜数万円程度

大規模(数億行〜、数百GB〜TB):

アプリ ──→ キャッシュ ──→ DB(Writer) ──→ SQS ──→ S3
──→ DB(Reader) ──→ 分析基盤

- 1つのDBでは限界(パーティション、Read/Write分離が必要)
- インデックスなしのクエリは数分〜タイムアウト
- ログは専用の集約基盤なしでは検索不能
- バックアップに数時間、RTO(復旧目標時間)の厳密な設計が必要
- コストは月額数十万円〜、設計次第で10倍の差

大量データで顕在化する5つの問題

小規模では隠れていた問題が、データ量の増加とともに表面化します。

1. レイテンシの非線形増加

データ量が10倍になると、レイテンシは10倍ではなく100倍以上に悪化することがあります。

テーブル行数とフルスキャン所要時間:

行数 フルスキャン インデックス検索
───── ────────── ────────────
10万行 50ms 1ms
100万行 500ms 1ms
1,000万行 5秒 2ms
1億行 50秒〜 3ms ← インデックスなしでは実用不可
10億行 タイムアウト 5ms

教訓: 小規模では「全件スキャンでも速い」が、大規模では
インデックスとパーティションの設計が生死を分ける

2. コストの非線形増加

「データ量に比例したコスト」は楽観的すぎます。データ量が増えると、周辺コスト(I/O、転送、バックアップ等)が加速度的に増加します。

データ量ストレージコストI/Oコストバックアップ合計目安
10GB$3/月$5/月含まれる$10/月
100GB$25/月$50/月$10/月$100/月
1TB$250/月$500/月$100/月$1,000/月
10TB$2,500/月$5,000/月$1,000/月$10,000/月

この差はストレージ階層化やクエリ最適化の設計で大きく変わります(後述のコスト最適化の柱を参照)。

3. 障害の影響範囲の拡大

小規模では「再起動すれば直る」障害が、大規模では「復旧に数時間、データ不整合のリスク」に変わります。

小規模での障害:
DB再起動 → 数秒でサービス復旧 → 影響軽微

大規模での障害:
DB再起動 → バッファプール再構築(数分)
→ キャッシュコールドスタート(数分)
→ 大量リクエストがDBに直撃(雪崩)
→ タイムアウト連鎖
→ 復旧に30分〜数時間

4. 運用の複雑化

運用タスク小規模大規模
デプロイ停止して更新、数分ローリング更新、数十分〜
マイグレーションALTER TABLE、数秒オンラインDDL必須、数時間
バックアップ検証手動でリストア確認自動リストア訓練が必須
ログ調査grep で十分専用分析基盤(Athena等)が必要
パフォーマンス監視基本メトリクスで十分テナント別・エンドポイント別メトリクスが必須

5. セキュリティリスクの増大

データ量が増えるほど、漏洩時の影響が大きくなります。

データ量漏洩時の影響必要な対策レベル
ユーザー1万人分重大だが限定的基本的な暗号化、アクセス制御
ユーザー100万人分社会的影響大データ分類別暗号化、監査ログの改ざん防止
ユーザー1,000万人分規制当局への報告義務エンベロープ暗号化、コンプライアンス対応、リアルタイム異常検知

この記事の読み方

以降のセクションでは、これらの問題に対するWell-Architected Frameworkの柱ごとの設計パターンを解説します。

問題                 → 対応する柱
────────── ──────────
レイテンシの悪化 → パフォーマンス効率(キャッシュ、パーティション、非同期処理)
コストの膨張 → コスト最適化(階層化、ライフサイクル、クエリ最適化)
障害影響の拡大 → 信頼性(バックアップ、整合性、バックプレッシャー)
セキュリティリスク増大 → セキュリティ(暗号化、分類、監査ログ保全)
運用の複雑化 → 運用上の優秀性(ログ集約、メトリクス、パイプライン監視)

データ特性の分類

各柱の設計パターンに入る前に、データそのものの特性を理解します。この分類が、以降のすべての設計判断の土台になります。

ホット/ウォーム/コールドデータ

データをアクセス頻度に基づいて分類し、それぞれに適したストレージとアクセス戦略を選択します。

分類アクセス頻度レイテンシ要件具体例適したストレージ
ホット常時アクセス(秒〜分単位)ミリ秒セッション、アクティブトークンElastiCache, DynamoDB
ウォーム定期的(時間〜日単位)最近の監査ログ、直近のユーザーデータAurora, S3 Standard
コールドまれ(月〜年単位)分〜時間過去の監査ログ、アーカイブデータS3 Glacier, S3 IA

この分類が重要なのは、すべてのデータをホットデータとして扱うと、コストが数十倍に膨らむからです。例えば1TBの監査ログをすべてElastiCacheに保持するとGB単価はS3 Glacierの約5,000倍になります。データの温度を正しく判断し、適切なストレージに配置することが大量データ設計の出発点です。

具体的なTTL設計やライフサイクル管理の実践は、コスト最適化の柱で詳しく解説します。

アクセスパターン

ワークロードのアクセスパターンを理解することで、適切なデータストアとインデックス戦略を選択できます。

パターン特徴設計のポイント適したサービス
読み取り中心読み取りが書き込みの10倍以上キャッシュ層、リードレプリカ活用Aurora Reader, ElastiCache
書き込み中心大量のINSERT/UPDATE非同期書き込み、バッチ処理DynamoDB, SQS + Aurora
混在読み書きが同程度Read/Write分離、CQRSAurora Writer + Reader
バースト特定時間帯に集中Auto Scaling、キューイングSQS + Auto Scaling

自分のワークロードがどのパターンに該当するかを把握しておくと、以降の各柱での設計判断がスムーズになります。


アプリケーションとインフラの責務

大量データの設計パターンを導入する際、「どこまでがアプリケーション(コード)の仕事で、どこからがインフラ(AWSサービス構築・設定)の仕事か」を明確にすることが重要です。この境界が曖昧だと、「インフラチームがElastiCacheを構築したのにアプリがDBに直接アクセスし続ける」「アプリが非同期書き込みを実装したのにSQSキューが存在しない」といった問題が起きます。

責務の基本原則

アプリケーション(idp-server)の責務:
「何をどう処理するか」のロジック

・どのデータをキャッシュに書くか、読むか
・どのクエリをReaderに向けるか、Writerに向けるか
・どのデータを非同期で書くか、同期で書くか
・サーキットブレーカーの発動条件と縮退動作
・カスタムメトリクスの計算と送信
・構造化ログの出力とコンテキスト付与

インフラ(AWS)の責務:
「どこに、どれだけ」のリソース提供と設定

・ElastiCacheクラスターの構築とサイジング
・Aurora Readerの追加とエンドポイント設定
・SQSキューの作成とDLQ設定
・API Gatewayのスロットリング設定
・CloudWatchアラーム・ダッシュボードの設定
・S3ライフサイクルポリシーの設定

パターン別 責務マトリクス

以降の各柱で解説するパターンについて、アプリとインフラの責務を整理します。

パターンアプリケーション(コード変更)インフラ(AWS構築・設定)連携ポイント
多層キャッシュキャッシュの読み書きロジック、TTL値の指定、キャッシュ無効化の実装ElastiCacheクラスター構築、ノードタイプ選定、CloudFront設定接続先エンドポイント、TTL値の合意
Read/Write分離読み取りクエリをReaderへ、書き込みをWriterへルーティングAurora Readerインスタンス追加、各エンドポイントの設定Reader/Writerのエンドポイント情報
非同期処理SQSへのメッセージ送信、コンシューマーの実装、DLQメッセージの再処理SQSキュー作成、DLQ設定、コンシューマー用のタスク定義キュー名/URL、メッセージフォーマット
パーティショニングクエリにパーティションキー(created_at等)を必ず含めるテーブルパーティション作成、pg_partmanによる自動管理パーティション粒度(月次等)の合意
コネクション管理コネクションプールサイズの設定RDS Proxy構築、Aurora最大接続数の調整接続先をDB直接→RDS Proxyに変更
バックプレッシャーサーキットブレーカー実装、バルクヘッド(コネクション分離)API Gatewayスロットリング設定、WAFレートリミットスロットリング閾値の合意
グレースフルデグラデーション縮退レベルの実装(機能のON/OFF制御、フォールバック処理)Auto Scaling設定、ヘルスチェック縮退レベルの定義と合意
ストレージ階層化S3への書き込み時にパーティション構造(year/month/day)に従うS3ライフサイクルポリシー設定、ストレージクラス遷移ルールパス構造の合意
データライフサイクルTTL値の設定(Redis TTL、トークン有効期限等)Aurora自動バックアップ設定、S3ライフサイクル、パーティションの自動DROP保持期間の要件定義
暗号化特になし(透過的暗号化)KMSキー作成、S3/Aurora/EBSの暗号化有効化
監査ログ保全ログ書き込み時のフォーマット準拠S3 Object Lock設定、ライフサイクルポリシー書き込み先バケットの指定
ログ集約構造化ログの出力、テナントID等のコンテキスト付与CloudWatch Logs設定、Firehose→S3パイプライン、Athenaテーブル定義ログフォーマットの合意
カスタムメトリクスメトリクス値の計算・送信(テナント別リクエスト数等)CloudWatchダッシュボード、アラーム設定メトリクス名・ディメンションの定義

共通の落とし穴

落とし穴症状対策
インフラだけ用意してアプリ未対応ElastiCacheを構築したが、アプリがDBに直接アクセスし続けるインフラ変更とアプリ変更をセットで計画する
アプリだけ変更してインフラ未準備非同期書き込みコードを実装したが、SQSキューが存在しないIaCで環境構築を先行させる
連携ポイントの認識ズレReader/Writer分離したが、接続先の環境変数が未設定設定項目の一覧を両チームで共有する
責務の押し付け合い「キャッシュ無効化はインフラ側でやるべき」と議論が停滞上記マトリクスで事前に合意する
段階的導入の同期ズレPhase 2のインフラを先行構築して月額コスト増、アプリ対応は3ヶ月後Phase単位でインフラとアプリの変更を同時にリリース

パフォーマンス効率の柱

大量データ環境でのパフォーマンス効率は、適切なデータストア選択、パーティショニング、キャッシュ戦略、非同期処理の組み合わせで実現します。ただし、各パターンには導入の代償があります。闇雲に全部入れるのではなく、ボトルネックに対して必要なものを選ぶことが重要です。

データストアの選択

「万能なデータストアは存在しない」ことを前提に、ワークロード特性に最適なサービスを選択します。

ワークロードデータストア選択理由
セッション管理ElastiCache(Redis)ミリ秒応答、TTL自動削除、キーバリュー操作
ユーザーデータAurora PostgreSQLリレーショナル、ACID、複雑なクエリ
監査ログ(書き込み)DynamoDB / Aurora高スループット書き込み(詳細はAurora vs DynamoDBを参照)
監査ログ(分析)S3 + Athena大量データの低コスト保存、SQLクエリ
ファイル/ドキュメントS3無制限ストレージ、高耐久性
フルテキスト検索OpenSearch全文検索、ログ分析
レポート/集計Redshift / Athenaカラム型、大量データの集計

迷ったときは以下の順に判断を分岐させます。

データストア選択のフローチャート:

①データの性質は?
|
+----+----+
| |
構造化 非構造化
| |
| +----+----+
| | |
| ファイル ログ/検索
| | |
| S3 OpenSearch
|
②レイテンシ要件は?
|
+----+----+
| |
ミリ秒 秒〜
| |
| ③クエリの複雑性は?
| |
| +----+----+
| | |
| 複雑 単純
| (JOIN, (キー検索,
| 集計, 範囲検索)
| トランザクション)
| | |
| | ④書き込みスループットは?
| | |
| | +----+----+
| | | |
| | 〜数千/秒 数万/秒〜
| | | |
ElastiCache Aurora DynamoDB
(Redis) PostgreSQL

Aurora vs DynamoDB — どちらも選べるときの判断基準

監査ログのように「どちらでも実現できる」ケースでは、以下の軸で判断します。

判断軸Aurora PostgreSQLDynamoDB
クエリの柔軟性高い(SQL、JOIN、サブクエリ、集計)低い(下記の「検索の制約」を参照)
書き込みスループット〜数千/秒(Writer 1台に集中)数万〜数百万/秒(パーティション分散、自動スケール)
スケーリング垂直スケール中心(Writer)+ Reader追加水平スケール(自動、無制限に近い)
コストモデルインスタンス時間課金(安定コスト)リクエスト課金 or キャパシティ予約(変動コスト)
運用負荷パーティション管理、インデックス設計が必要フルマネージド、運用ほぼ不要
トランザクション完全なACID制限付き(25アイテム、4MBまで)
全文検索LIKEtsvectorで対応可単体では不可(OpenSearch連携が必要)

DynamoDBの検索の制約: DynamoDBは「パーティションキー(PK)の完全一致 + ソートキー(SK)の範囲検索」が基本のクエリモデルです。例えば PK=tenant-a, SK BETWEEN 2024-01-01 AND 2024-02-01 のように「テナント内の時間範囲検索」はできますが、以下は単純にはできません。

クエリ例DynamoDBAurora
tenant-aの2024年1月のログPK+SKで可能SQLで可能
tenant-aのlogin_failureイベントだけGSI追加か複合SKが必要WHERE event_type = ?
全テナントの今月のログイン失敗数全パーティションスキャン(非現実的)SELECT COUNT(*)
tenant-aの月別件数集計集計関数なし、アプリ側で処理GROUP BY

つまりDynamoDBの監査ログ利用は「大量に書き込んで、テナント+時間範囲で取得するだけ」のパターンに限定されます。条件検索や集計が必要な場合、DynamoDBに書き込んでもS3にエクスポートしてAthenaで分析する構成が必要です。

判断の目安:

「テナントのログを様々な条件で検索・集計したい」
→ Aurora(SQLの柔軟性が必要)

「秒間数万件の書き込みが必要、検索はテナント+時間範囲のみ」
→ DynamoDB(書き込みスループットとスケーラビリティ)
※ 条件検索・集計が必要なら S3 + Athena を後段に追加

「書き込み性能も検索柔軟性も両方必要」
→ Aurora(書き込み)+ S3/Athena(大量分析)
Aurora単体で数千/秒の書き込みは可能。それで足りない場合のみDynamoDBを検討

メッセージング/イベントサービスの選択基準

非同期処理やイベント駆動では、SQS、SNS、EventBridge、Kinesisが候補になります。

判断軸SQSSNSEventBridgeKinesis Data Streams
主な用途ワーカー間のタスク分散1対多の通知配信イベントルーティング大量ストリーム処理
配信モデルPull(コンシューマが取得)Push(サブスクライバーに配信)Push(ルールに基づく配信)Pull(シャードから取得)
スループットほぼ無制限(標準キュー)ほぼ無制限秒間数千イベントシャードあたり1MB/秒 or 1000レコード/秒
順序保証FIFOキューで保証可能なしなしシャード内で保証
メッセージ保持最大14日保持しない(即時配信)なし(即時配信)最大365日
リプレイ不可不可アーカイブからリプレイ可任意の時点から再読み取り可
コストリクエスト課金リクエスト課金イベント課金シャード時間課金

よくある組み合わせパターンを知っておくと選びやすくなります。

  SNS + SQS(ファンアウト)
1つのイベントを複数のキューに配信
例: 認証成功 → 監査ログキュー + 統計キュー + 通知キュー

EventBridge + SQS/Lambda(イベント駆動)
ルールに基づいてイベントを振り分け
例: event_type = "login_failure" → Lambda(アラート処理)
event_type = "token_issued" → SQS(統計集計)

Kinesis + Lambda(リアルタイム分析)
大量イベントの連続処理と再読み取り
例: 秒間数万の認証イベントのリアルタイム異常検知

パーティショニング

テーブルサイズが大きくなるとクエリパフォーマンスが低下します。パーティショニングにより、スキャン対象を限定しパフォーマンスを維持します。

Auroraテーブルパーティション

-- 時系列データの範囲パーティション例(監査ログ)
CREATE TABLE audit_logs (
id BIGINT NOT NULL,
tenant_id VARCHAR(255) NOT NULL,
event_type VARCHAR(100) NOT NULL,
created_at TIMESTAMP NOT NULL,
payload JSONB,
PRIMARY KEY (id, created_at)
) PARTITION BY RANGE (created_at);

-- 月次パーティション
CREATE TABLE audit_logs_2024_01 PARTITION OF audit_logs
FOR VALUES FROM ('2024-01-01') TO ('2024-02-01');
CREATE TABLE audit_logs_2024_02 PARTITION OF audit_logs
FOR VALUES FROM ('2024-02-01') TO ('2024-03-01');

-- パーティション作成の自動化(pg_partman等を利用)

DynamoDB パーティションキー設計

DynamoDBではパーティションキーの設計がパフォーマンスを左右します。ホットパーティションを避けるために、アクセスが均等に分散するキー設計が必要です。

パターンパーティションキーソートキーユースケース
テナント分離tenant_idcreated_atテナント別の時系列データ
複合キーtenant_id#event_typecreated_atテナント+イベント種別での絞り込み
シャーディングtenant_id#shard_Ncreated_at大量書き込みテナントのホットキー分散

導入のトレードオフ: パーティショニングはクエリパフォーマンスを改善しますが、パーティション境界をまたぐクエリ(例: 月をまたぐ期間検索)のプラン最適化や、パーティションの作成・削除の運用自動化が必要になります。pg_partman等のツールを使わないと、パーティションの管理自体が運用負荷になります。

責務の分担: アプリ → クエリにパーティションキー(WHERE created_at BETWEEN ...)を必ず含める、パーティション境界をまたぐ検索時のロジック / インフラ → パーティションテーブルの作成(DDL)、pg_partmanによる自動管理、古いパーティションのDROP/アーカイブ

多層キャッシュ戦略

大量読み取りを効率的に処理するために、複数のキャッシュ層を組み合わせます。

いつ必要になるか: Aurora Reader だけでは捌けないほど読み取りが多い場合です。目安として、Reader のCPU使用率が常時70%を超える、またはp99レイテンシが許容値を超え始めたら、キャッシュ層の追加を検討します。逆に、読み取りが多くない段階でキャッシュを入れると、無駄なコストと複雑性を抱え込むだけです。

リクエスト
|
v
+------------------+ ヒット: 1-5ms
| CloudFront | ──→ 静的コンテンツ、API応答のキャッシュ
| (エッジキャッシュ) | TTL: 秒〜分
+--------+---------+
| ミス
v
+------------------+ ヒット: 1-2ms
| ElastiCache | ──→ セッション、トークン、頻繁に参照するデータ
| (Redis) | TTL: 分〜時間
+--------+---------+
| ミス
v
+------------------+ 応答: 2-10ms
| Aurora Reader | ──→ マスターデータ、ユーザー情報
| (リードレプリカ) |
+--------+---------+
| 書き込み
v
+------------------+
| Aurora Writer | ──→ データ更新の正本
| (プライマリ) |
+------------------+

導入のトレードオフ: キャッシュ層を増やすほど、キャッシュ無効化の複雑さが増します。「ユーザーが設定を変更したのに古い情報が表示される」問題は、キャッシュの典型的な落とし穴です。TTL自動削除だけで済む場合(セッション、トークン等)は運用しやすいですが、マスターデータのキャッシュでは明示的な無効化の仕組みが必要になります。また、ElastiCacheのインスタンス費用は常時発生するため、キャッシュヒット率が低いと費用対効果が悪化します。

責務の分担: アプリ → キャッシュの読み書きロジック(cache-aside パターン等)、TTL値の指定、データ変更時のキャッシュ無効化 / インフラ → ElastiCacheクラスター構築・サイジング、CloudFrontディストリビューション設定

非同期処理パターン

大量の書き込みやピーク時のリクエストを、キューを使って平準化します。同期処理では処理しきれない負荷を安全に捌くパターンです。

同期処理(ピーク時にスロットリングが発生):

クライアント ──→ API ──→ DB
↑ 書き込み集中でタイムアウト

非同期処理(キューで平準化):

クライアント ──→ API ──→ SQS ──→ Lambda/ECS ──→ DB
即時応答 ↑ 安定した
(202) バッファ 書き込み速度

いつ必要になるか: 書き込みのピークと平均の比率が3倍以上あるとき、またはピーク時にDBタイムアウトが発生し始めたときが導入の目安です。監査ログのように「書き込みのレスポンスをクライアントに返す必要がない」データは、非同期化の良い候補です。

導入のトレードオフ: 非同期処理では**「書き込みが本当に成功したか」の確認が難しくなります**。SQSからのコンシューマが処理に失敗した場合のリトライ、デッドレターキュー(DLQ)の監視と再処理の設計が必要です。また、書き込みからDBに反映されるまでにタイムラグが生じるため、「書いた直後に読む」ユースケースには向きません。メッセージングサービスの選択は前述のメッセージング/イベントサービスの選択基準を参照してください。

責務の分担: アプリ → SQSへのメッセージ送信ロジック、コンシューマーの実装(DB書き込み処理)、DLQメッセージの再処理ロジック / インフラ → SQSキュー・DLQの作成、コンシューマー用Lambda/ECSタスク定義、リトライポリシーの設定

コネクション管理

大量のアプリケーションインスタンスがDBに接続する環境では、コネクション枯渇が深刻な問題になります。RDS Proxyでコネクションプーリングを一元管理します。

RDS Proxyなし:

ECS タスク1 ──→ [10接続] ──→
ECS タスク2 ──→ [10接続] ──→ Aurora (最大接続数: 1000)
... ↑
ECS タスク100──→ [10接続] ──→ 1000接続で上限到達!

RDS Proxyあり:

ECS タスク1 ──→ [10接続] ──→
ECS タスク2 ──→ [10接続] ──→ RDS Proxy ──→ [100接続] ──→ Aurora
... 多重化&再利用
ECS タスク100──→ [10接続] ──→ 1000→100に圧縮

いつ必要になるか: アプリケーションのインスタンス数 x コネクションプールサイズがDBの最大接続数の50%を超えたら検討します。Auto Scalingでインスタンスが増減する環境では特に重要です。

導入のトレードオフ: RDS Proxyの追加コスト(vCPU時間課金)が発生します。また、Proxyを経由することでわずかにレイテンシが増加します(通常1ms未満)。小規模な固定台数の環境では、アプリケーション側のコネクションプール設定の調整で十分なことが多いです。

責務の分担: アプリ → コネクションプールサイズの設定(HikariCPのmaximumPoolSize等)、接続先エンドポイントの切り替え(DB直接→RDS Proxy) / インフラ → RDS Proxyの構築、Aurora最大接続数の調整、ターゲットグループ設定


信頼性の柱

大量データを扱うシステムでは、データの消失や不整合が致命的な問題になります。どのデータにどのレベルの耐久性・整合性が必要かを見極め、過剰でも不足でもない設計を目指します。

データ耐久性の設計

AWSの各ストレージサービスは異なる耐久性レベルを提供します。データの重要度に応じて適切なサービスを選択します。

サービス耐久性レプリケーション備考
S3 Standard99.999999999%(イレブンナイン)3つ以上のAZに自動複製オブジェクトストレージの標準
Aurora99.999999999%3つのAZに6つのコピー2つのコピー消失でも読み取り可能
EBS99.999%同一AZ内で複製AZ障害で影響あり
ElastiCacheレプリケーション設定によるマルチAZレプリカ設定時キャッシュなので消失を許容する設計が前提

ここで重要なのは、ElastiCacheの耐久性は設計で補う必要があるということです。キャッシュの消失時にDBからデータを再構築できる設計にしておくことが前提です。キャッシュを「唯一の正本」にしてはいけません。

バックアップ戦略

RPO(Recovery Point Objective: どこまでのデータ損失を許容するか)とRTO(Recovery Time Objective: どれだけ早く復旧するか)に基づいてバックアップ戦略を選択します。

戦略RPORTOコストユースケース
Aurora自動バックアップ5分(PITR)数分〜数十分低(含まれる)標準的なデータ保護
Aurora手動スナップショットスナップショット間隔数十分マイルストーン前のバックアップ
クロスリージョンレプリカ秒〜分リージョン障害対策
S3クロスリージョン複製即時(S3)監査ログ、アーカイブの冗長化
DynamoDBグローバルテーブル即時(読み取り)グローバルアクティブ/アクティブ

大量データ環境では、バックアップの「リストアにかかる時間」がRTOを超えないかを事前に検証することが重要です。100GBのDBのリストアは10GBの10倍以上かかることがあります。定期的なリストア訓練を怠ると、いざというときに「復旧が間に合わない」事態になります。

整合性モデル

大量データを分散環境で扱う場合、「全データが常に最新」を保証するにはコストがかかります。ユースケースに応じて整合性レベルを使い分けます。

整合性モデルの選択:

データの種類 整合性モデル 理由
───────────── ────────── ────
認証・認可判定 ──→ 強い整合性 誤判定は許容できない
トークン失効 ──→ 強い整合性 失効トークンの使用を防ぐ
ユーザープロフィール ──→ セッション整合性 同一ユーザーの操作は即時反映
監査ログ一覧 ──→ 結果整合性 数秒の遅延は許容できる
統計ダッシュボード ──→ 結果整合性 リアルタイム性は不要

判断の原則: 「誤った古いデータを返すと何が起きるか?」を問います。認証判定で古いデータを使えばセキュリティ事故、監査ログ一覧で数秒遅れても実害なし。この影響度で整合性レベルを決めます。全データに強い整合性を要求するとスケーラビリティが大幅に制限されるため、ここでの適切な緩和が大量データ環境の設計で最も重要な判断の一つです。

バックプレッシャー制御

大量書き込みが発生した際に、システムが過負荷で崩壊しないようにするメカニズムです。

バックプレッシャーなし(障害連鎖):

大量リクエスト ──→ API ──→ DB ──→ タイムアウト

コネクション枯渇

全リクエスト失敗

バックプレッシャーあり(制御された劣化):

大量リクエスト ──→ APIスロットリング ──→ SQS ──→ DB
↓ 安定した速度で処理
429 Too Many Requests
(一部リクエストを制御)
手法実装効果
APIスロットリングAPI Gateway スロットリングリクエスト数を制限
キューイングSQS による非同期処理書き込みピークの平準化
サーキットブレーカーアプリケーション実装障害の連鎖を遮断
バルクヘッドコネクションプール分離障害の影響範囲を限定

責務の分担: アプリ → サーキットブレーカーの実装(発動条件・復帰条件の定義)、バルクヘッドパターン(コネクションプールの分離) / インフラ → API Gatewayスロットリング設定、WAFレートリミットルール、SQSキューによるバッファリング

グレースフルデグラデーション

全機能を停止させるのではなく、優先度の低い機能から段階的に縮退させることで、コア機能を守ります。IDサービスでは「認証・トークン発行」が最も優先度の高い機能です。

通常時:
認証 ✓ | トークン発行 ✓ | 監査ログ ✓ | 統計表示 ✓ | フルテキスト検索 ✓

高負荷時(レベル1):
認証 ✓ | トークン発行 ✓ | 監査ログ ✓ | 統計表示 △ | フルテキスト検索 ✗
キャッシュのみ 一時停止

障害時(レベル2):
認証 ✓ | トークン発行 ✓ | 監査ログ △ | 統計表示 ✗ | フルテキスト検索 ✗
非同期キューへ 停止 停止

設計のポイント: この縮退レベルは事前に定義し、チーム全体で合意しておく必要があります。障害発生中に「何を止めてよいか」を議論している余裕はありません。

責務の分担: アプリ → 縮退レベルごとの機能ON/OFF制御の実装、フォールバック処理(例: DB障害時にキャッシュのみで応答) / インフラ → Auto Scaling設定、ヘルスチェックの定義、障害検知からの自動復旧設定


コスト最適化の柱

大量データの保管コストは、設計次第で桁違いに変わります。データのライフサイクルに応じた階層化と、クエリコストの最適化が鍵です。

ストレージ階層化

S3の豊富なストレージクラスを活用し、アクセスパターンに応じてコストを最適化します。

ストレージクラス料金/GB/月(目安)取り出しコストユースケース
S3 Standard$0.025なし頻繁にアクセスするデータ
S3 IA$0.0125あり(GB単位)月に1回程度のアクセス
S3 Intelligent-Tiering$0.025 + 監視料なしアクセスパターンが不明
S3 Glacier IR$0.004あり(ミリ秒取得)四半期に1回のアクセス
S3 Glacier FR$0.0036あり(分〜時間)年に1-2回のアクセス
S3 Glacier DA$0.00099あり(12時間)7-10年保持の規制対応
ライフサイクルポリシーによる自動遷移:

0日 30日 90日 365日 2555日
| | | | |
作成 ──→ [Standard] ──→ [IA] ──→ [Glacier IR] ──→ [Glacier DA] ──→ 削除
$0.025/GB $0.0125 $0.004 $0.00099
7年保持後に自動削除

データライフサイクル管理

ここが大量データのコスト管理で最も重要なセクションです。各データのTTL(生存期間)を設計段階で定義し、自動的にアーカイブ・削除する仕組みを作ります。「不要データの蓄積」はコスト膨張の最大の原因です。

データ種別保持期間保管先自動化方式なぜこの期間か
セッション24時間ElastiCacheRedis TTLユーザーの操作間隔を超える
アクセストークン1時間ElastiCache / DBTTL / バッチ削除セキュリティと利便性のバランス
リフレッシュトークン7日〜90日Auroraバッチ削除再認証頻度の要件
認可コード10分ElastiCacheRedis TTLRFC 6749推奨
監査ログ(アクティブ)90日Aurora / DynamoDBパーティション DROP運用でリアルタイム検索が必要な期間
監査ログ(アーカイブ)7年S3 Glacierライフサイクルポリシー法規制・コンプライアンス要件
セキュリティイベント1年S3 Standard → IAライフサイクルポリシーインシデント調査の必要性
バックアップ35日Aurora自動バックアップRDS設定1ヶ月前のデータまで復元可能

注意: ライフサイクルを設定せずに放置すると、1年後には「監査ログだけで数TBのストレージ」という状態になり得ます。データ量の見積もりは「1日のイベント数 x 365日 x 平均イベントサイズ」で事前に計算しておくべきです。

クエリコストの最適化

大量データに対するクエリは、設計次第でコストが大きく変動します。

Athena のパーティション設計

S3に保存した大量データをAthenaでクエリする場合、パーティション設計が直接コストに影響します(スキャンしたデータ量に課金)。

パーティションなし:
s3://bucket/audit-logs/data.parquet ← 全データスキャン: 1TB = $5

パーティションあり:
s3://bucket/audit-logs/
year=2024/
month=01/
day=15/
data.parquet ← 1日分スキャン: 1GB = $0.005

コスト1000分の1に削減!
最適化手法効果実装方法
パーティションスキャン量削減(10〜1000倍改善)年/月/日のディレクトリ構造
カラムナフォーマット必要な列のみスキャンParquet / ORC 形式で保存
圧縮スキャン量の物理削減gzip / snappy 圧縮
CTAS結果のマテリアライズCREATE TABLE AS SELECT

Aurora のI/O最適化

料金モデル特徴適したワークロード
StandardI/O課金(読み書き回数)I/O量が少ないワークロード
I/O-OptimizedI/O無制限(インスタンス料金が40%増)I/O量が多いワークロード

目安: I/OコストがAurora総コストの25%を超える場合、I/O-Optimizedが有利です。

マルチテナントのコスト配分

マルチテナント環境では、テナント間でインフラを共有するため「どのテナントがどれだけリソースを消費しているか」の可視化が必要です。

手法説明粒度
AWSコスト配分タグリソースにテナントタグを付与リソース単位
アプリケーションメトリクステナント別のAPI呼び出し数・データ量を記録リクエスト単位
S3プレフィックス別集計テナント別のプレフィックスでストレージ使用量を把握オブジェクト単位
CloudWatch カスタムメトリクステナント別のリソース消費量をメトリクスとして記録任意の単位

セキュリティの柱

大量データを扱う環境では、暗号化の効率性、データ分類に基づくアクセス制御、監査ログの改ざん防止が重要な設計ポイントです。

大量データの暗号化

大量データの暗号化では、エンベロープ暗号化により暗号化/復号の効率性とキー管理のセキュリティを両立します。

エンベロープ暗号化:

+------------------+
| KMS |
| (CMK: マスターキー) | ← 直接データを暗号化するのではなく
+--------+---------+ データキーを暗号化
|
データキー生成
|
+------v------+
| データキー | ← このキーでデータを暗号化
| (平文) | S3/EBS/RDSの暗号化に使用
+------+------+
|
+------v------+
| 暗号化された | ← データキー自体もCMKで暗号化して保存
| データキー |
+-------------+

利点:
- 大量データの暗号化はローカルのデータキーで高速に実行
- KMSへのAPI呼び出しはキー操作時のみ(データ量に依存しない)
- キーローテーション時もデータの再暗号化は不要

なぜエンベロープ暗号化が必要かというと、KMSで直接暗号化できるデータサイズは最大4KBに限られるからです。大量データを扱う場合、KMS API呼び出し回数も膨大になり、レイテンシとコストの両方が問題になります。

データ分類とアクセス制御

すべてのデータを同じセキュリティレベルで保護するのは非効率です。データの機密度に応じて保護レベルを定義します。

機密度レベルデータ例暗号化アクセス制御監査
最高秘密鍵、マスターキーCMK(カスタマー管理)最小限のIAMロール全アクセスログ
パスワードハッシュ、PIICMK(カスタマー管理)サービス固有のロール書き込みログ
監査ログ、メタデータAWS管理キーサービスロール設定変更ログ
公開設定、静的コンテンツAWS管理キーまたは不要読み取り広め不要

大量監査ログの保全

監査ログは改ざん防止と長期保存が求められます。S3 Object Lockにより、WORM(Write Once Read Many)モデルを実現します。

改ざん防止のアーキテクチャ:

アプリケーション
|
監査ログ書き込み
|
v
+------------------+
| S3バケット |
| Object Lock | ← Complianceモード: 期間内は誰も削除/変更不可
| (WORM) | (rootアカウントでも不可)
+------------------+
|
ライフサイクルポリシー
|
v
+------------------+
| S3 Glacier DA | ← 長期保存(コスト最小化)
| Object Lock維持 | Object Lockは遷移後も維持
+------------------+

コンプライアンス

大量データを扱う際は、法規制とデータ居住要件への対応が必須です。

要件対応方法AWSサービス
データ居住(国内保管)東京リージョンの使用を強制S3バケットポリシー、SCP
保持期間ライフサイクルポリシーで最低保持期間を設定S3 Object Lock
アクセス記録全アクセスのCloudTrailログを保全CloudTrail + S3
暗号化義務バケットポリシーで暗号化を強制S3バケットポリシー
定期監査AWS Configルールで継続的にコンプライアンスチェックAWS Config

運用上の優秀性の柱

大量データ環境では、ログの集約・分析、メトリクス設計、データパイプラインの可視化が運用の品質を左右します。

大規模ログの集約と分析

ログの量と目的に応じて、適切な分析ツールを使い分けます。

ツール適したユースケースコスト特性クエリ速度
CloudWatch Logs Insights直近のアプリケーションログ検索取り込み量課金秒(直近データ)
AthenaS3上の大量ログのSQLクエリスキャン量課金秒〜分
OpenSearchリアルタイムログ分析、ダッシュボードインスタンス課金ミリ秒〜秒

小規模のうちはCloudWatch Logs Insightsで十分です。ログが増えてCloudWatchのコストが膨らんだり、検索が遅くなったら、S3にエクスポートしてAthenaに移行します。リアルタイムダッシュボードが必要になったタイミングでOpenSearchを検討します。

ログの集約アーキテクチャ:

ECS タスク CloudWatch Logs
+-----------+ +------------------+
| アプリログ | ──awslogs──→ | ロググループ |
+-----------+ | /ecs/idp-server |
+--------+---------+
|
サブスクリプション
フィルター
|
+----------------+----------------+
| |
v v
+------------------+ +------------------+
| Kinesis Firehose | | Lambda |
| | | (アラート処理) |
+--------+---------+ +------------------+
|
v
+------------------+
| S3 | ← 長期保存 + Athenaクエリ
| (パーティション |
| year/month/day) |
+------------------+

カスタムメトリクスの設計

大量データ環境では、標準メトリクスだけでは不十分です。テナント別・エンドポイント別のカスタムメトリクスにより、異常を早期に検知します。

メトリクスディメンションアラーム条件用途
リクエスト数テナントID, エンドポイント急激な増加(通常の5倍)異常アクセス検知
レスポンスタイム(p99)エンドポイント500ms超過パフォーマンス劣化検知
エラーレートテナントID, HTTPステータス5%超過障害検知
DB接続使用率インスタンスID80%超過キャパシティ管理
キャッシュヒット率キャッシュクラスター70%未満に低下キャッシュ効率低下検知
キューのメッセージ滞留キュー名1000件超過処理遅延検知

注意: ディメンションが多すぎるとCloudWatchのコストが膨らみます。テナントIDをディメンションに含める場合、テナント数が数千を超えるとメトリクス数が爆発するため、上位N件のみに限定する、または集約して送るなどの工夫が必要です。

責務の分担(ログ集約・メトリクス共通): アプリ → 構造化ログの出力(JSON形式)、テナントID等のコンテキスト付与、カスタムメトリクス値の計算・送信 / インフラ → CloudWatch Logs設定、Kinesis Firehose→S3パイプライン構築、Athenaテーブル定義、CloudWatchダッシュボード・アラーム設定

データパイプラインの監視

大量データを処理するパイプラインでは、各ステップの状態を可視化し、異常を素早く特定できることが重要です。

Step Functionsによるパイプライン可視化:

┌─────────────┐
│ 日次バッチ │ ← EventBridgeスケジュール(毎日02:00)
│ トリガー │
└──────┬──────┘

┌──────▼──────┐
│ データ抽出 │ ← Aurora → S3エクスポート
│ (Extract) │ 状態: 成功/失敗/所要時間
└──────┬──────┘

┌──────▼──────┐
│ データ変換 │ ← Lambda/Glueで加工
│ (Transform) │ 状態: 処理件数/エラー件数
└──────┬──────┘

┌──────▼──────┐
│ データ格納 │ ← S3パーティション配置
│ (Load) │ 状態: 書き込みサイズ
└──────┬──────┘

┌──────▼──────┐
│ 完了通知 │ ← SNS通知(成功/失敗)
└─────────────┘

IDサービスの統合アーキテクチャ

ここまで柱ごとに個別の設計パターンを解説してきました。実際のシステムでは、これらのパターンが組み合わさって1つのアーキテクチャを形成します。IDサービス(idp-server)を例に、全体像を示します。

データの流れと各パターンの配置

                        IDサービス 大量データアーキテクチャ全体像

┌─────────┐
│クライアント│
└────┬────┘

┌────▼────┐
│CloudFront│ ・・・・・・ [キャッシュ: 静的コンテンツ、JWKS]
└────┬────┘

┌────▼────┐ ┌──────────────┐
│ ALB │───→│API スロットリング│ ・・ [バックプレッシャー]
└────┬────┘ └──────────────┘

┌────▼─────────────────────────────────────────────────┐
│ ECS Fargate (idp-server) │
│ │
│ 認証リクエスト処理 │
│ │ │
│ ├── セッション読み書き ──→ ElastiCache (Redis) │
│ │ ↕ [ホットデータ、TTL管理] │
│ │ Aurora (永続化) │
│ │ │
│ ├── ユーザーデータ検索 ──→ Aurora Reader │
│ │ [Read/Write分離] │
│ │ │
│ ├── トークン発行/検証 ──→ ElastiCache (キャッシュ) │
│ │ [Introspection高速化] │
│ │ │
│ └── セキュリティイベント発行 ──→ EventBridge │
│ │ │
└────────────────────────────────────│──────────────────┘

┌───────────────────────┼───────────────────────┐
│ │ │
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────────┐
│ SQS │ │ Lambda │ │ CloudWatch │
│ (監査ログ) │ │ (アラート)│ │ (メトリクス) │
└────┬─────┘ └────┬─────┘ └──────────────┘
│ │
▼ ▼
┌──────────┐ ┌──────────┐
│ Lambda │ │ SNS │
│ (書き込み) │ │ (通知) │
└──┬───┬───┘ └──────────┘
│ │
▼ ▼
┌────────┐ ┌────────────┐
│ Aurora │ │ S3 (Parquet)│
│(直近90日)│ │ (長期保存) │
│パーティション│ │ Object Lock │
└────────┘ └─────┬──────┘

ライフサイクル


┌────────────┐
│ S3 Glacier │
│ (7年保存) │
└────────────┘

この図で使われているパターンの一覧

パターンこの記事のセクション統合図での役割
多層キャッシュパフォーマンス効率CloudFront → ElastiCache → Aurora Reader
非同期処理パフォーマンス効率セキュリティイベント → EventBridge → SQS → 書き込み
コネクション管理パフォーマンス効率ECS Fargate ↔ RDS Proxy ↔ Aurora(図では省略)
パーティションパフォーマンス効率Aurora の監査ログテーブル(月次パーティション)
バックプレッシャー信頼性ALB + API スロットリング
グレースフルデグラデーション信頼性統計・検索は停止しても認証は維持
ストレージ階層化コスト最適化Aurora(90日) → S3(Standard) → S3(Glacier)
データライフサイクルコスト最適化ElastiCache TTL、パーティション DROP、ライフサイクルポリシー
監査ログ保全セキュリティS3 Object Lock (WORM)
イベントルーティングパフォーマンス効率EventBridge → SQS/Lambda/CloudWatch の振り分け
ログ集約運用上の優秀性CloudWatch Logs → Kinesis Firehose → S3 → Athena

マルチテナントのデータ分離

統合アーキテクチャの中で、テナント間のデータ分離は以下のように実現されます。

分離レベル方式コスト分離度適用
カラム分離共有テーブル + tenant_id標準的なマルチテナント
スキーマ分離テナント別スキーマ規制要件がある場合
DB分離テナント別DBインスタンス最高金融・医療等

idp-serverでは「カラム分離」を採用しています。全テーブルに tenant_id カラムがあり、全クエリに WHERE tenant_id = ? が含まれます。インデックスは (tenant_id, ...) の複合インデックスを基本とし、テナント内の検索を高速に保ちます。


段階的な導入パス

ここまでの設計パターンをすべて最初から導入する必要はありません。データ量の成長に合わせて、段階的に対策を追加していくのが現実的なアプローチです。

Phase 1: 基盤(テーブル行数〜数百万行)

最初から入れておくべき基本的な設計です。後から変更するとコストが大きいものを中心に。

対策:
✓ テーブル設計に tenant_id を含める(後から追加は困難)
✓ 主要テーブルにインデックスを設計する
✓ Aurora自動バックアップを有効化(35日保持)
✓ CloudWatch Logsでアプリケーションログを集約
✓ データのTTLを設計ドキュメントに定義する(実装は後でもよい)
✓ 全ストレージの暗号化を有効化

まだ不要:
× キャッシュ層(Aurora単体で十分速い)
× 非同期処理(書き込み量が少ない)
× パーティショニング(テーブルが小さい)
× RDS Proxy(インスタンス数が少ない)

Phase 1 のコスト目安

テナント数: 〜10、ユーザー数: 〜1万、データ量: 〜10GB

EKS Fargate × 2 Pod (1vCPU/2GB): 約 $140
EKS コントロールプレーン: 約 $73
Aurora Serverless v2 (0.5〜4 ACU): 約 $300
CloudWatch Logs: 約 $20
ALB + Route 53: 約 $26
暗号化 (KMS): 約 $5
─────────────────────────────────────
合計: 約 $560/月

※ Well-Architected本編の小規模(約$650)との差額はElastiCacheの有無。
本編は「本番環境の全体構成」としてキャッシュを含むが、
ここでは「Phase 1ではキャッシュ不要」の判断を反映している。

Phase 2: 成長期(テーブル行数 数千万行〜、書き込み 数百/秒〜)

パフォーマンスやコストに兆候が出始めたら導入する対策です。

導入トリガーと対策:

「DBのCPU使用率が常時60%超」
→ ElastiCache導入(セッション、トークンのキャッシュ)
→ Aurora Reader追加(Read/Write分離)

「監査ログテーブルのクエリが遅い」
→ テーブルパーティション導入(月次)
→ 90日超のデータをS3にアーカイブ開始

「ピーク時に書き込みタイムアウトが発生」
→ 監査ログの非同期書き込み(SQS経由)

「ログ検索に時間がかかる」
→ CloudWatch LogsからS3+Athenaへの移行開始

「インスタンスがAuto Scalingで増えるとDB接続数が不安定」
→ RDS Proxy導入

Phase 2 のコスト目安

テナント数: 〜100、ユーザー数: 〜10万、データ量: 〜100GB

Phase 1からの増分 Phase 1: $560
──────────────────────────────────────
+ EKS マネージドノード t3.xlarge × 3 +$317 (Fargate→EC2ノードへ移行)
+ Aurora db.r6g.xlarge (Writer+Reader) +$660 (Serverless→プロビジョンドへ移行)
+ ElastiCache cache.r7g.large × 2 +$368
+ RDS Proxy: +$290
+ S3 (監査ログアーカイブ 100GB): +$3
+ Athena (月10クエリ): +$1
+ SQS (非同期書き込み): +$1
+ CloudWatch (メトリクス強化): +$30
+ WAF: +$25
─────────────────────────────────────
合計: 約 $2,250/月

※ Phase 1比で約4倍。増分の大半はElastiCache、Aurora拡張、RDS Proxy

Phase 3: 大規模運用(テーブル行数 数億行〜、テナント数 数百〜)

本格的な大規模運用に必要な対策です。

導入トリガーと対策:

「S3のストレージコストが月額数十万円超」
→ ライフサイクルポリシーの本格運用(S3 → Glacier自動遷移)
→ Athenaクエリのパーティション+Parquet最適化

「テナントごとのリソース消費差が大きい」
→ テナント別メトリクスの導入
→ コスト配分タグの設計

「セキュリティ監査への対応が必要」
→ S3 Object Lockによる監査ログ保全
→ クロスリージョンレプリケーション

「障害時の復旧に時間がかかる」
→ リストア訓練の定期実施
→ グレースフルデグラデーションの設計と合意
→ バックプレッシャー制御の導入

「リアルタイムの異常検知が必要」
→ EventBridge + Lambda によるセキュリティイベントのリアルタイム処理

Phase 3 のコスト目安

テナント数: 〜1000、ユーザー数: 〜100万、データ量: 〜1TB+

コンピュート:
EKS マネージドノード r6g.xlarge × 6: 約 $1,320
EKS コントロールプレーン: 約 $73

データストア:
Aurora db.r6g.2xlarge (W+R×2): 約 $2,550
ElastiCache cache.r7g.xlarge × 3: 約 $1,100
RDS Proxy: 約 $760

ストレージ・分析:
S3 Standard (200GB アクティブログ): 約 $5
S3 Glacier (2TB アーカイブ): 約 $7
Athena (月100クエリ、パーティション済み): 約 $5

ネットワーク・配信:
ALB + NAT Gateway + CloudFront: 約 $200

監視:
CloudWatch + X-Ray: 約 $150

セキュリティ:
WAF + Shield Advanced: 約 $3,100
KMS: 約 $30

非同期処理:
SQS + EventBridge + Lambda: 約 $20
─────────────────────────────────────
合計: 約 $9,300/月

※ Shield Advancedは$3,000/月の固定費。
DDoS保護が不要なら WAF のみで約$100に削減可能 → 合計約$6,300/月

Phase間のコスト推移

月額コスト
$10,000 ┤
│ ┌─────────
$9,000 ┤ ┌┘ Phase 3
│ ┌┘
$6,000 ┤ ┌┘
│ ┌┘
│ ┌──────────┘
$2,250 ┤ ┌───────────┘ Phase 2
│ ┌┘
$560 ┤─────────────┘ Phase 1

$0 ┼──────────────────────────────────────────────→
〜1万 〜10万 〜100万 ユーザー数

コスト増加の主な要因:
Phase 1→2: ElastiCache導入、Aurora拡張、RDS Proxy
Phase 2→3: コンピュート増強、Aurora増強、Shield Advanced

コスト最適化の適用効果(各Phase共通)

施策削減率適用先
Gravitonインスタンス約20%EC2ノード、Aurora、ElastiCache
リザーブドインスタンス(1年)30〜40%Aurora、ElastiCache
Savings Plans(1年)20〜30%コンピュート全体
ライフサイクルポリシー50〜90%S3ストレージ(IA/Glacier遷移)
Athenaパーティション90〜99%クエリコスト(スキャン量削減)
Aurora I/O-OptimizedI/O量次第I/OがDB料金25%超の場合
最適化適用後の目安:

Phase 1: $560 → $480 (Graviton適用)
Phase 2: $2,250 → $1,350 (Graviton + RI + Savings Plans)
Phase 3: $9,300 → $5,800 (Graviton + RI + Savings Plans, Shield除く)

導入判断のフローチャート

  現在、パフォーマンスやコストに問題はあるか?
|
+----+----+
| |
No Yes
| |
Phase 1で どの兆候が出ているか?
十分 |
+----+----+----+----+
| | | | |
DB遅い コスト増 書込み ログ 接続枯渇
| | 遅延 検索困難 |
| | | | |
Phase 2の該当する対策を導入
|
改善されたか?
|
+----+----+
| |
Yes No
| |
監視継続 Phase 3の対策を検討

アンチパターン

大量データ設計で陥りやすい失敗パターンです。

アンチパターン問題正しいアプローチ
単一DBにすべてを詰め込むスケールの限界、パフォーマンス劣化ワークロード特性に応じてデータストアを分離
ホットとコールドを同一階層で保存コスト浪費、不要データによるクエリ低速化ライフサイクルポリシーでストレージ階層を自動遷移
キャッシュ戦略なしで大量読み取りDBへの不要な負荷集中多層キャッシュ(CloudFront → ElastiCache → Reader)
ログを無期限保持ストレージコストの膨張TTL設計と自動アーカイブ/削除
パーティション設計なしの巨大テーブルフルスキャンによるクエリ低速化時系列パーティション + 適切なインデックス
同期書き込みのみピーク時のタイムアウト、障害連鎖非同期キューイングによるピーク平準化
全データに強い整合性を要求不要なレイテンシ増加、スケーラビリティ制限ユースケースに応じた整合性モデルの使い分け
コネクションプーリングの未考慮スケールアウト時のコネクション枯渇RDS Proxyの導入
最初から全パターンを導入する不要な複雑性とコスト兆候に応じて段階的に導入

まとめ

  • 大量データは質的な変化: 小規模で通用した設計が破綻する。レイテンシ、コスト、障害影響、運用複雑性、セキュリティリスクのすべてが非線形に増大する
  • データ分類が出発点: ホット/ウォーム/コールドの分類と、アクセスパターンの理解が全設計判断の土台
  • 適材適所のサービス選択: Aurora vs DynamoDB、SQS vs EventBridge vs Kinesis — ワークロード特性で判断する。万能なサービスは存在しない
  • パターンにはトレードオフがある: キャッシュは無効化の複雑さを、非同期処理はデバッグの難しさを、パーティションは運用管理をそれぞれ引き受けることになる
  • 段階的に導入する: Phase 1(基盤設計)→ Phase 2(兆候に応じた対策)→ Phase 3(大規模運用)。最初から全部入れる必要はない
  • 統合的に考える: 個別パターンの理解だけでなく、IDサービスのように複数パターンが組み合わさった全体像を把握することが重要

次のステップ

参考リソース