マルチリージョン運用3年で実感した、Route 53では足りなかった3つの課題

グローバル展開で「Route 53があれば大丈夫」と思ってた僕たちが、直面した予想外の問題。失敗から学んだ実装パターンを図解で解説します。

マルチリージョン運用3年で知った、Route 53だけじゃ足りない理由

うちのチームがグローバル展開を始めたのは3年前。当時は「Route 53で DNS ラウンドロビンすれば大丈夫」と楽観的に考えてました。その甘さを本当に思い知らされました。

シンガポール拠点の立ち上げ直後、東京のユーザーから「なぜかシンガポール経由でアクセスされてる」というクレームが。Route 53 のジオロケーションルーティングを設定していたのに、トラフィックが最適でない地域にルーティングされていたんです。その時初めて気づきました。DNS ルーティングだけではマルチリージョンネットワーク設計は完成しないということを。

3年かけて何度も失敗しながら辿り着いた、2026年時点での実装パターンを共有します。

Route 53の限界と、実装して気づいたこと

Route 53 でできること・できないことを整理してみたんですが、正直に言うと DNS レベルの制御だけだと足りません。

Route 53 でできていることって、見た目より限定的なんですよ。

機能説明特徴
ジオロケーションルーティング国・都道府県ベースで振り分け静的な地理情報のみ参照
加重ルーティングトラフィック分散比を指定固定比率
フェイルオーバーヘルスチェック時に自動切り替えバイナリ(動く/動かない)
レイテンシベースルーティングユーザーに最も近いリージョン優先リアルタイム情報なし

一見すごそうですが、これらは静的な設定なんです。うちが直面した問題をざっくりいうと:

問題1:リアルタイムなトラフィック状況が反映されない

Route 53 のレイテンシベースルーティングは「どのリージョンが地理的に近いか」で判定するんですが、実際のネットワークって混雑状況で変わるんです。東京と大阪のように距離は近いけど、その時間帯に大阪経由の方が高速ってことが起きます。うちの場合、ゴールデンウィークに東京リージョンが混雑して、本来ならシンガポール経由の方が速いのに Route 53 は東京を優先していた。ユーザー体験は最悪でした。

問題2:NLB / ALB レベルのコネクション管理が独立している

Route 53 が「シンガポールにアクセスせよ」と指示しても、実際のコネクションが NLB でどう処理されるかは別の話なんです。3年前は「リージョン間でコネクション数が偏ってバックエンドが過負荷になる」という問題を何度も経験しました。

問題3:TLS ハンドシェイクのコスト

DNS が各リージョンに振り分けても、ユーザーは毎回 TLS ハンドシェイクを最初から始める必要があります。これって意外とレイテンシに効いてくるんですよ。特にモバイルでは。

AWS Global Accelerator を本気で検証した6ヶ月

問題に直面してから、我々が導入したのが AWS Global Accelerator です。1年前は「過剰機能では?」と思ってましたが、実装してみて本当に変わりました。

Global Accelerator の何が違うのか:

Route 53(DNS ベース)
ユーザー → DNS 問い合わせ → IP アドレス取得 → リージョンへ接続
          (毎回、キャッシュ効かないと往復)

Global Accelerator(エニーキャスト + TCP/UDP)
ユーザー → 最寄りの AnyPoint(固定 IP) → AWS 高速バックボーン → リージョン
          (ファイアウォール通しやすい、TLS 再開可能)

実装してみて体感できた変化:

  • レイテンシが平均30%改善:単にリージョン選定がスマートになっただけじゃなく、AWS バックボーン経由で高速化したから
  • モバイルユーザーで大幅改善:キャリアネットワークの不安定さを Global Accelerator が吸収している
  • TLS セッション再開:同じ Global Accelerator の IP 経由なら既存セッション情報を活用できて、ハンドシェイクが省略される場合もある

ただ、導入してから気づいた落とし穴もあります。

Global Accelerator の意外な制約:

導入6ヶ月目で目が覚めたんですが、実は全能ではないんです。

  1. リージョン間のコネクション管理は相変わらず統一されていない:Global Accelerator は「どのリージョンに送るか」を判定するだけで、その後のコネクションプールは各リージョンの NLB が独立管理。つまり東京リージョンに大量のコネクションが溜まって、シンガポール側は遊んでる、みたいなことが起きます。

  2. コスト:月30万円近く。スケールしたサービスなら OK ですが、小〜中規模だと Route 53 + CloudFront + 自前の最適化の方が安いかもしれない。

  3. キャッシュ戦略が複雑化:Global Accelerator が複数リージョンに振り分けると、キャッシュヒット率が下がるんです。うちは CloudFront をさらに前に置く結果になって、層が増えてデバッグが地獄になりました。

マルチリージョン設計で本当に重要な3つのレイヤー

3年の試行錯誤から気づいたんですが、マルチリージョンって実は3層構造で考えるべきなんです。

1. エッジ層:ユーザーに最も近い場所

CloudFront + Global Accelerator の組み合わせですね。

  • 静的コンテンツ:CloudFront のエッジロケーション(200以上)でキャッシュしてレスポンス
  • 動的コンテンツ&リアルタイム系:Global Accelerator の Anycast IP 経由で AWS バックボーン直結

うちが実装した構成:

ユーザー

[CloudFront エッジロケーション]
  ├─ キャッシュ可能 → Cache キャッシュしてレスポンス
  └─ 動的コンテンツ → Global Accelerator Anycast IP へ

[AWS Global Accelerator]

[各リージョンの NLB/ALB]

2. リージョン層:計算リソースの配置

ここが意外と複雑です。ECS・EKS・Lambda のどれを選ぶかで、マルチリージョン戦略が変わります。

ECS Fargate でやってた時代の失敗

各リージョンで独立した ECS クラスタを立てていたら、リージョン間のコネクションプール管理が破綻しました。東京にタスク 10 個、シンガポールに 5 個いるのに、DNS ラウンドロビンで振ると、東京のリソースが飽和する現象。

EKS に乗り換えてからの改善

EKS にして始めてカスタムコントローラーで「グローバルコネクションプール」を実装できたんです。

# イメージ:EKS のカスタムリソース
apiVersion: networking.mycompany.com/v1
kind: GlobalLoadBalancer
metadata:
  name: api-global
spec:
  regions:
    - name: ap-northeast-1
      target: tokyo-nlb
      weight: 50      # コネクション数の目安
      readiness: true
    - name: ap-southeast-1
      target: sg-nlb
      weight: 30
      readiness: true
    - name: us-east-1
      target: us-nlb
      weight: 20
      readiness: true
  strategy: dynamic-weight-adjustment
  healthCheckInterval: 5s

この構成で、実際のバックエンド負荷に基づいてリアルタイムに重みを調整できるようになりました。

3. データレプリケーション層:状態管理

ここがマルチリージョン設計で最も複雑で、ほぼ全ての企業が失敗してます。うちも例外ではありませんでした。

うちが学んだ教訓:

RDS Multi-AZ だけでは足りないってすぐに気づきました。クロスリージョンレプリケーションは RPO / RTO の要件で大きく変わります。

Aurora Global Database でやってた時代は、写入は東京だけで、読み取り専用レプリカが各リージョン。結構安定していました。でも、切り替わり時間が問題で、2年前のある障害で東京リージョン全体がダウンした時、RTO が 5 分かかった。その後は DynamoDB + Global Tables に乗り換えました。

DynamoDB Global Tables の何が良かったのか:

Aurora Global Database(読み取り専用レプリカ)
東京リージョン ─ 書き込み → レプリケーション → シンガポール ─ 読み取りのみ

DynamoDB Global Tables(全リージョン読み書き)
東京 ←→ シンガポール ←→ 米国
(最終的一貫性で自動同期)

DynamoDB にしてから、RTO がほぼ 0 に近くなりました。代わりに「最終的一貫性」の設計を強いられましたが、うちのユースケースでは OK でした。

2026年現在の、うちのマルチリージョン構成

実際に運用してる構成を図にしてみました。

graph TB
    subgraph EdgeLayer ["Edge Layer: CloudFront + Global Accelerator"]
        CF["CloudFront CDN<br/>200+ Locations"]
        GA["AWS Global Accelerator<br/>Anycast IP"]
    end

    subgraph TokyoRegion ["Tokyo Region (ap-northeast-1)"]
        TkyAZ1["AZ 1a"]
        TkyAZ2["AZ 1c"]
        
        subgraph TkyNetwork ["VPC: 10.0.0.0/16"]
            TkyNLB["NLB<br/>Port 80, 443"]
            TkyEKS["EKS Cluster<br/>8x t3.xlarge"]
            TkyAurora["Aurora PostgreSQL<br/>Primary"]
        end
        
        TkyAZ1 --> TkyNLB
        TkyAZ2 --> TkyNLB
        TkyNLB --> TkyEKS
        TkyEKS --> TkyAurora
    end

    subgraph SGRegion ["Singapore Region (ap-southeast-1)"]
        SgAZ1["AZ 1a"]
        SgAZ2["AZ 1b"]
        
        subgraph SgNetwork ["VPC: 10.1.0.0/16"]
            SgNLB["NLB<br/>Port 80, 443"]
            SgEKS["EKS Cluster<br/>6x t3.large"]
            SgDDB["DynamoDB<br/>Global Tables"]
        end
        
        SgAZ1 --> SgNLB
        SgAZ2 --> SgNLB
        SgNLB --> SgEKS
        SgEKS --> SgDDB
    end

    subgraph USRegion ["US East Region (us-east-1)"]
        UsAZ1["AZ 1a"]
        UsAZ2["AZ 1b"]
        
        subgraph UsNetwork ["VPC: 10.2.0.0/16"]
            UsNLB["NLB<br/>Port 80, 443"]
            UsEKS["EKS Cluster<br/>4x t3.medium"]
            UsS3["S3 Replica<br/>Async"]
        end
        
        UsAZ1 --> UsNLB
        UsAZ2 --> UsNLB
        UsNLB --> UsEKS
        UsEKS --> UsS3
    end

    subgraph CrossRegion ["Cross-Region"]
        Transit["Transit Gateway<br/>for Inter-Region"]
        AuroraSync["Aurora Replication<br/>Tokyo → Sg/Us<br/>Read-only"]
        DDBSync["DynamoDB Global Tables<br/>Bi-directional Sync"]
    end

    User["User<br/>Global Access"]
    
    User --> CF
    User --> GA
    CF --> TkyNLB
    GA --> TkyNLB
    GA --> SgNLB
    GA --> UsNLB
    
    TkyNLB --> Transit
    SgNLB --> Transit
    UsNLB --> Transit
    
    TkyAurora --> AuroraSync
    AuroraSync --> SgDDB
    AuroraSync --> UsS3
    
    TkyDDB["DynamoDB<br/>Global Tables"] -.-> DDBSync
    SgDDB -.-> DDBSync
    UsS3 -.-> DDBSync
    
    style EdgeLayer fill:#ff9999
    style TokyoRegion fill:#99ccff
    style SGRegion fill:#99ff99
    style USRegion fill:#ffcc99
    style CrossRegion fill:#cc99ff

実装で痛感したコスト最適化のポイント

マルチリージョンはコストがエグいです。うちが3年で学んだ工夫を紹介しますね。

1. リージョン間通信をできるだけ減らす

Transit Gateway は便利ですが、データ転送料がかかります。月平均 200GB のクロスリージョン通信で月 18万円かかってました。正直、目を疑いましたね。

対策は こんな感じ:

  • 可能な限りリージョンローカルで完結するようアプリ設計する
  • DynamoDB Global Tables は「同期」が多くないユースケースのみ利用
  • S3 は非同期レプリケーション + CloudFront キャッシュで対応

これで月8万円まで削減できました。

2. 全リージョンで同じスペックはいらない

東京(写入+読み取り)は大きく、シンガポール(読み取り+軽い計算)は中程度、米国(バックアップ + 非同期処理)は小さく。これって当たり前ですが、実装時には意外と見落とされます。

うちの構成:

  • 東京:t3.xlarge × 8 ノード(EKS)
  • シンガポール:t3.large × 6 ノード
  • 米国:t3.medium × 4 ノード

Spot Instance Mix で月 30% 削減できてます。

3. Global Accelerator は「本当に必要か」検討する

Route 53 + CloudFront で十分な場合も多いんです。うちが Global Accelerator を導入した理由は「ライブストリーミング配信」と「リアルタイムチャット」で低レイテンシが必須だったから。他のサービスだったら不要かもしれません。

運用して分かった、本番環境のモニタリング戦略

マルチリージョンは複雑なので、層別で監視する必要があります。

① DNS 層

  • Route 53 Health Checks
  • ジオロケーション別レスポンスタイム

② グローバルエッジ層

  • Global Accelerator Flow Logs
  • 地域別・リージョン別のトラフィック分散率
  • TLS ハンドシェイク成功率

③ リージョン層

  • CloudWatch メトリクス(各リージョン EKS)
  • CPU / メモリ使用率
  • NLB コネクション数
  • ポッド起動時間

④ クロスリージョン層

  • Transit Gateway Flow Logs
  • 帯域幅利用率
  • パケット損失率

⑤ データレイヤー

  • Aurora Global Database レプリケーション遅延
  • DynamoDB Global Tables レプリケーション遅延
  • S3 クロスリージョンレプリケーション遅延

僕たちはこれら全部を Datadog に集約してダッシュボード化してます。3年前は CloudWatch だけで監視してて、クロスリージョン障害に気づくのが遅かった教訓から。今では問題を早期発見できるようになりました。

まとめ

マルチリージョン設計は「Route 53 で振り分ければ OK」という簡単な話ではありません。3年の経験から気づいたポイント:

  1. Route 53 は DNS ルーティングに過ぎない:本当の最適化には Global Accelerator、CloudFront、アプリケーション層での工夫が必要です。

  2. リージョン間コネクション管理が複雑:独立した各リージョンのリソースをどう統合するかは、アーキテクチャの工夫次第。EKS にして初めて実装できました。

  3. データレプリケーション戦略で大きく変わる:Aurora か DynamoDB か、同期か非同期か、要件でがらりと変わる。最適解は1つではありません。

  4. コスト最適化は必須:やみくもにマルチリージョン化するとコストが爆発します。要件に合わせた「段階的」な展開を心がけるべき。

  5. 監視・アラートが重要:マルチリージョンは複雑なので、問題発生時に気づく仕組みが全てを決めます。

次は「マルチリージョン障害から 30 分で自動復旧する設計」をチームで実装しようとしてます。正直、まだ検証中だけど、早ければ Q1 に導入予定。またハマった話は別の記事で書きますね。

U

Untanbaby

ソフトウェアエンジニア|AWS / クラウドアーキテクチャ / DevOps

10年以上のIT実務経験をもとに、現場で使える技術情報を発信しています。 記事の誤りや改善点があればお問い合わせからお気軽にご連絡ください。

関連記事