LESSON 40分

ストーリー

高橋アーキテクト
東京のデータセンターが丸ごと落ちたら、サービスはどうなる?
高橋アーキテクト
…止まります
高橋アーキテクト
それがシングルリージョンの限界だ。マルチリージョンは、地理的に分散することでリージョン障害に耐え、かつ世界中のユーザーに低レイテンシを提供する。ただし、代償としてデータの一貫性が複雑になる

マルチリージョンのパターン

// 3つのマルチリージョンパターン
const MULTI_REGION_PATTERNS = {
  activePassive: {
    name: "Active-Passive (DR)",
    description: "1リージョンがActive、もう1つがスタンバイ",
    dataFlow: "Active → 非同期レプリケーション → Passive",
    failover: "手動 or 自動フェイルオーバー(数分〜数十分)",
    consistency: "非同期レプリケーションによるデータロスの可能性",
    cost: "低〜中(Passiveはスタンバイ)",
    useCase: "DR要件はあるがコストを抑えたい場合",
  },
  activeActive: {
    name: "Active-Active",
    description: "複数リージョンが同時にトラフィックを処理",
    dataFlow: "双方向レプリケーション",
    failover: "即座(DNSルーティングで切り替え)",
    consistency: "競合解決が必要(CRDTやLast Write Wins)",
    cost: "高(全リージョンがフル稼働)",
    useCase: "グローバルサービス、最高可用性",
  },
  readLocalWriteGlobal: {
    name: "Read Local, Write Global",
    description: "読み取りは最寄りリージョン、書き込みはプライマリリージョン",
    dataFlow: "Write → Primary → 非同期レプリカ → ローカル読み取り",
    failover: "読み取りは即座、書き込みはフェイルオーバー",
    consistency: "結果整合性(読み取り時に古いデータの可能性)",
    cost: "中",
    useCase: "読み取りヘビーなサービス(コンテンツ配信等)",
  },
};

データレプリケーション

// 同期 vs 非同期レプリケーション
const REPLICATION_STRATEGIES = {
  synchronous: {
    description: "プライマリとセカンダリの両方に書き込みが完了してからACK",
    consistency: "強い一貫性",
    latency: "高い(リージョン間RTT: 100-300ms)",
    availability: "レプリカ障害時に書き込みがブロックされる",
    useCase: "金融、決済など一貫性が最優先",
  },
  asynchronous: {
    description: "プライマリに書き込み完了後にACK、セカンダリへは後から伝播",
    consistency: "結果整合性(レプリケーションラグあり)",
    latency: "低い(プライマリのみで完了)",
    availability: "障害時のデータロスの可能性(RPO > 0)",
    useCase: "ほとんどのWebサービス",
  },
  semiSynchronous: {
    description: "少なくとも1つのレプリカに同期書き込み",
    consistency: "中程度の一貫性保証",
    latency: "中程度",
    availability: "1レプリカ障害に耐えられる",
    useCase: "バランスが必要な場合",
  },
};

競合解決

// Active-Activeでの書き込み競合の解決
interface ConflictResolution {
  strategy: string;
  description: string;
  tradeoff: string;
}

const CONFLICT_RESOLUTION_STRATEGIES: ConflictResolution[] = [
  {
    strategy: "Last Write Wins (LWW)",
    description: "タイムスタンプが新しい方を採用",
    tradeoff: "実装が簡単だがデータロスの可能性",
  },
  {
    strategy: "CRDT (Conflict-free Replicated Data Type)",
    description: "データ構造自体が競合を自動解決",
    tradeoff: "データロスなしだが、使えるデータ構造が限定的",
  },
  {
    strategy: "Application-level Resolution",
    description: "アプリケーションロジックで競合を解決",
    tradeoff: "柔軟だが実装が複雑",
  },
  {
    strategy: "Region-based Sharding",
    description: "データのオーナーリージョンを決め、そこでのみ書き込み",
    tradeoff: "競合自体を回避できるが、リージョン間の書き込みが必要な場合に課題",
  },
];

グローバルルーティング

// DNSベースのルーティング
const ROUTING_STRATEGIES = {
  geolocation: {
    method: "地理的位置ベースのDNSルーティング",
    how: "ユーザーのIPアドレスから最寄りのリージョンに誘導",
    tool: "Route 53 Geolocation Routing / Cloudflare Load Balancing",
  },
  latency: {
    method: "レイテンシベースのルーティング",
    how: "各リージョンへのレイテンシを計測し、最速のリージョンに誘導",
    tool: "Route 53 Latency Routing",
  },
  failover: {
    method: "ヘルスチェックベースのフェイルオーバー",
    how: "プライマリリージョンの障害を検出し自動でセカンダリに切り替え",
    tool: "Route 53 Failover Routing + Health Checks",
  },
};

// 全体アーキテクチャ
// ユーザー → Global DNS → 最寄りリージョンの CDN/Edge
//                        → 最寄りリージョンの API サーバー
//                        → ローカル読み取りレプリカ
//                        → 書き込みはプライマリリージョンへ転送

RPOとRTO

// 障害復旧の指標
interface DisasterRecoveryMetrics {
  // RPO (Recovery Point Objective): データロスの許容量
  rpo: {
    definition: "障害時にどこまでのデータを失ってよいか";
    synchronousReplication: "RPO = 0(データロスなし)";
    asynchronousReplication: "RPO = レプリケーションラグ(秒〜分)";
    dailyBackup: "RPO = 最大24時間";
  };

  // RTO (Recovery Time Objective): 復旧までの許容時間
  rto: {
    definition: "障害からサービス復旧までの許容時間";
    activeActive: "RTO ≈ 0(即座にフェイルオーバー)";
    activePassive: "RTO = 数分〜数十分";
    backupRestore: "RTO = 数時間";
  };
}

// RPO/RTOの目標に応じた構成選択
const DR_CONFIGURATIONS = [
  { rpo: "0",       rto: "< 1分",    config: "Active-Active + 同期レプリケーション", cost: "最高" },
  { rpo: "< 1分",   rto: "< 5分",    config: "Active-Passive + 非同期レプリカ",    cost: "高" },
  { rpo: "< 1時間", rto: "< 30分",   config: "Active-Passive + 定期スナップショット", cost: "中" },
  { rpo: "< 24時間",rto: "< 4時間",  config: "バックアップ + 別リージョン復元",      cost: "低" },
];

まとめ

ポイント内容
3つのパターンActive-Passive, Active-Active, Read Local Write Global
レプリケーション同期(一貫性重視)vs 非同期(レイテンシ重視)
競合解決LWW, CRDT, リージョンシャーディング
RPO/RTO目標に応じた構成とコストのトレードオフ

チェックリスト

  • 3つのマルチリージョンパターンを比較できた
  • 同期/非同期レプリケーションのトレードオフを理解した
  • 競合解決の戦略を3つ以上挙げられた
  • RPO/RTOに基づくDR構成を選択できた

次のステップへ

次は演習です。ミッションクリティカルなシステムの設計に挑戦しましょう。


推定読了時間: 40分