ベストプラクティス
アーキテクチャパターン、設計原則、最適化戦略
このガイドでは、数多くのデプロイで実績のあるアーキテクチャパターン、設計原則、最適化戦略を紹介します。
設計原則
1. シンプルに始め、段階的に拡張する
最初から過剰に設計しないでください。現在の要件を満たす最もシンプルな設計から始め、発展させましょう。
良い例: データベース 1 台、アプリサーバー 1 台、ロードバランサー 悪い例: 初日から 5 リージョンにマイクロサービスを展開し、イベントソーシングを導入する
2. 障害を前提に設計する
コンポーネントは故障するものと考え、冗長化と段階的な機能縮退を組み込みます。
良い例: マルチ AZ データベース、フェイルオーバーレプリカ、サーキットブレーカー 悪い例: どこかに単一障害点がある
3. 最適化の前に測定する
データなしに最適化しないでください。分析モジュールと監視を活用します。
良い例: スケーラビリティ分析で実際のボトルネックを特定する 悪い例: 「データベースが遅そうだからキャッシュを追加しよう」
4. トレードオフを理解する
すべてのアーキテクチャ上の判断にはトレードオフがあります。記録しましょう。
良い例: 「市場投入を早めるためモノリスを選び、ユーザーが 10 万人になったらマイクロサービスに移行する」 悪い例: 「スケーラビリティのためマイクロサービスを追加しよう」(複雑性とのトレードオフを理解していない)
5. すべてを自動化する
手作業のプロセスは規模に対応できません。デプロイ、監視、スケーリングを自動化します。
良い例: Infrastructure as Code(Terraform)、オートスケーリンググループ、CI/CD パイプライン 悪い例: サーバーの手動プロビジョニング、手動のスケーリング判断
一般的なアーキテクチャパターン
パターン:モノリシック Web アプリケーション
適した場面: MVP、単一チーム、ユーザー 10 万人未満
トポロジー:
Users
↓
Load Balancer (ELB)
↓
App Servers (3+ instances, auto-scaled)
↓
Cache Layer (Redis)
↓
Database (Primary + Read Replicas)
↓
Object Storage (S3)長所:
- 開発とデバッグが容易
- デプロイと水平スケーリングが容易
- 運用負荷が低い
短所:
- コードベースが大きくなると保守しにくい
- 共有データベースがスケーリングの制約になる
- 言語やフレームワークに依存する
発展させるタイミング: ユーザーが 5 万人を超え、データベースがボトルネックになったとき
パターン:マイクロサービスアーキテクチャ
適した場面: 大規模チーム、ユーザー 10 万人超、複数サービス
トポロジー:
API Gateway
├─ Auth Service
├─ User Service
├─ Product Service
├─ Order Service
├─ Payment Service
├─ Notification Service
└─ Analytics Service
Shared Infrastructure:
- Service Mesh (Istio, Linkerd)
- Message Bus (Kafka, RabbitMQ)
- Distributed Tracing
- Centralized Logging長所:
- サービスごとに独立してスケーリングできる
- チームが自律的に作業できる
- 複数言語を含む技術選択の柔軟性
- 個々のサービスを容易にデプロイできる
短所:
- 運用が複雑になる
- 分散システム固有の課題(結果整合性、デバッグ)
- サービス間のネットワーク遅延
- 成熟した DevOps の実践が必要
適した場面: モノリスがボトルネックになり、かつ対応できるチーム体制が整っているとき
パターン:サーバーレス(FaaS)
適した場面: イベント駆動、変動する負荷、コスト重視のワークロード
トポロジー:
API Gateway
↓
Lambda Functions (auto-scaled to zero)
├─ DynamoDB (serverless database)
├─ S3 (object storage)
├─ SQS/SNS (messaging)
└─ CloudWatch Logs長所:
- 使用した実行時間だけ課金される
- アイドル時は自動でゼロまで縮小する
- 開発とデプロイが容易
- インフラ管理が不要
短所:
- コールドスタートの遅延
- 実行環境のカスタマイズに制限
- ベンダーロックイン(AWS Lambda、GCP Functions)
- 従来のサーバーよりデバッグが難しい
適した場面: 突発的なアクセス増、実行頻度の低い処理、運用リソースの少ないスタートアップ
パターン:データレイクと分析
適した場面: ビッグデータ、機械学習、分析ワークロード
トポロジー:
Data Sources (streaming + batch)
↓
Data Ingestion (Kafka, Kinesis, SQS)
↓
Data Lake (S3, Blob Storage)
↓
ETL/Transform (Spark, Glue, Dataflow)
↓
Data Warehouse (Redshift, BigQuery, Snowflake)
↓
BI/ML Tools (Tableau, DataStudio, SageMaker)考慮事項:
- データ品質とガバナンス
- スキーマの柔軟性(読み取り時スキーマと書き込み時スキーマ)
- 個人識別情報(PII)の取り扱いとプライバシー要件への準拠
- クエリ性能の最適化
最適化戦略
コスト最適化
1. リソースを適正サイズにする
- 最大容量ではなく実際の使用量を監視する
- CloudWatch などで利用傾向を把握する
- 過剰なリソースを持つインスタンスを縮小する
2. リザーブドインスタンス
- 定常的なワークロードを予測する
- 1〜3 年のリザーブドインスタンスを購入する(20〜40% 割引)
- 変動する負荷にはオートスケーリングを組み合わせる
3. スポットインスタンス
- 障害を許容できる非クリティカルな処理に使う
- オンデマンドより 70% 安い
- 2〜5% の中断率を見込む
4. キャッシュ戦略
- 頻繁にアクセスするデータをメモリにキャッシュする(Redis)
- データベース負荷を 50〜80% 削減する
- 静的アセットに CDN を使う(80% 以上のコスト削減)
5. データ転送の最適化
- 高額になりやすいのに見落とされがちなコスト要因
- VPC エンドポイントでデータ転送料を回避する
- 転送データを圧縮する
- グローバル配信に CloudFront を使う
スケーラビリティの最適化
1. 水平スケーリング
- ロードバランサー配下にサーバーを追加する
- データベース:リードレプリカを追加する(プライマリとレプリカ)
- キャッシュ:キャッシュノードを追加する
2. シャーディング(データベース)
- キー(ユーザー ID、リージョン、日付)でデータを分割する
- 各シャードを独立してスケーリングできる
- トレードオフはシャード間の調整の複雑さ
3. コネクションプーリング
- データベース接続を再利用する
- スループットが 2〜3 倍向上する
- 接続のオーバーヘッドを減らす
4. キャッシュ戦略
- アプリケーション層で頻繁に使うデータをキャッシュする
- 無効化戦略を設けて API レスポンスをキャッシュする
- ORM レベルでデータベースクエリをキャッシュする
セキュリティのベストプラクティス
1. 暗号化
- 転送時:すべてのエンドポイントで TLS 1.3
- 保存時:KMS キーによる AES-256
- データベース:暗号化ボリュームと、PII 向けアプリケーションレベル暗号化
2. 認証と認可
- 全ユーザーアカウントで MFA
- 外部連携には OAuth 2.0
- 最小権限の IAM ポリシー
- アプリ利用者には RBAC
3. ネットワークセキュリティ
- VPC で分離する(データベース用プライベートサブネット)
- 許可ポートを最小限にしたセキュリティグループ
- 追加の防御層として NACL
- ロードバランサーに WAF(Web アプリケーションファイアウォール)
4. データ保護
- PII のトークン化とマスキング
- 機密データのフィールド単位暗号化
- 古いデータを削除する保持ポリシー
- バックアップの復旧テスト
5. 監視と監査
- 全 API 呼び出しの CloudTrail・監査ログ
- 異常を検知する CloudWatch アラーム
- 定期的なセキュリティ監査
- インシデント対応ランブック
パフォーマンスのベストプラクティス
1. レイテンシーの最適化
- 静的アセットに CDN を使う
- よく使うクエリにデータベースインデックスを作る
- クエリを最適化する(N+1 クエリを避ける)
- API リクエストをバッチ処理する
2. スループットの最適化
- サーバー間で負荷分散する
- データベース接続をプーリングする
- 時間のかかる処理を非同期化する
- CPU 集約型ワークロードは垂直スケーリングする
3. 信頼性
- 自動復旧付きヘルスチェック
- 依存先へのサーキットブレーカー
- 指数バックオフ付き再試行
- 段階的な機能縮退
デプロイのベストプラクティス
1. Infrastructure as Code
- すべてを Terraform・CloudFormation で定義する
- バージョン管理する
- 適用前にピアレビューする
- まずステージングでテストする
2. 継続的デプロイ
- 自動テスト(単体、結合、E2E)
- カナリアデプロイ(段階的な展開)
- ブルーグリーンデプロイ(無停止)
- ロールバック戦略
3. 監視と可観測性
- 構造化ログ(JSON)
- 分散トレーシング(X-Ray、Jaeger)
- メトリクス収集(Prometheus、CloudWatch)
- エラーだけでなく SLO に基づくアラート
アンチパターン(避けるべきこと)
❌ どこかに単一障害点がある(冗長化なし) ❌ 過剰設計(成長で必要になる前に複雑化する) ❌ コストを無視する(不要な機能のためにサービスを選ぶ) ❌ 手動スケーリング(自動化すべき) ❌ 監視がない(状況が見えない) ❌ 災害復旧計画がない(期待だけでは戦略にならない) ❌ すべてを単一 AZ に置く(データセンター障害に弱い)