マルチリージョン構成とフェイルオーバ設計
リージョン障害でもサービスを止めない設計を原理から。active-activeとactive-passiveの選び方、RPO/RTOとレプリケーション遅延の関係、DNS切替とスプリットブレイン回避まで掴めます。
- 1.active-activeは全リージョンが本番トラフィックを捌き高可用・低レイテンシだが書き込み競合の解消が要る。active-passiveは待機系へ切替えるだけで単純だが切替時間と待機資源のコストを払う。
- 2.RPO(許容データ損失)はレプリケーションの同期性で、RTO(許容復旧時間)は障害検知+切替の遅さで決まる。非同期レプリケーションはレプリケーション遅延ぶんのデータをフェイルオーバで失う。
- 3.トラフィック切替はDNS(TTLとキャッシュ滞留が効く)かエニーキャスト(経路収束が速い)で行い、ヘルスチェックの誤検知と両系同時アクティブ化が招くスプリットブレインをフェンシングや過半数判定で防ぐ。
なぜ単一リージョンでは足りないのか
クラウドの可用性ゾーン(AZ)を複数束ねれば、サーバー故障やラック障害には耐えられます。しかしリージョン全体が落ちる事象——大規模停電、ネットワーク分断、コントロールプレーンのバグ、自然災害——はAZ冗長では救えません。マルチリージョン構成は、地理的に独立した複数のリージョンへサービスを展開し、片方が丸ごと失われても継続稼働させるための設計です。
ただしリージョンをまたぐと、光速の壁という物理が立ちはだかります。東京とバージニア間の往復は理論下限でも数十ミリ秒、実際には100ミリ秒を超えます。この遅延が、同期レプリケーションの代償・データの一貫性・切替の判断速度すべてに効いてきます。本記事は active-active/active-passive の選択、RPO/RTO とレプリケーション遅延の関係、そして DNS・エニーキャスト・ヘルスチェックによるトラフィック切替とスプリットブレイン回避を、原理から解きほぐします。
active-active と active-passive
構成の根幹は、全リージョンが本番トラフィックを捌くか(active-active)、片方が待機するか(active-passive)の選択です。
| 観点 | active-active | active-passive |
|---|---|---|
| トラフィック | 全リージョンが同時に処理 | アクティブ系のみ処理、待機系は受けない |
| 切替時間 (RTO) | 短い(生存系へ寄せるだけ) | 長い(待機系の昇格・暖機が要る) |
| 書き込み競合 | あり(複数地点で同時書込) | なし(書込はアクティブ系のみ) |
| レイテンシ | 最寄りリージョンで処理でき低い | アクティブ系から遠いと高い |
| コスト | 全系が本番容量で常時稼働 | 待機系を縮小可能だが暖機に時間 |
| 複雑度 | 高い(競合解消・冪等性が必須) | 低い(単一書込元で因果が単純) |
active-active の最大の難所は書き込みの競合です。複数リージョンが同じレコードを同時に更新すると、どちらを正とするかを決めねばなりません。解消戦略は概ね三系統です。(1) リージョン分割——ユーザーやテナントごとに「書き込み担当リージョン(home region)」を固定し、競合を構造的に起こさない。(2) last-write-wins——タイムスタンプで勝者を決めるが、クロックずれで更新を取りこぼす危険があり因果を壊す。(3) CRDT やバージョンベクタ——競合を検知してマージする。どの一貫性モデルを選ぶかは設計の核心で、強整合を全リージョンで保つには合意(コンセンサス)の往復が要り、リージョン間 RTT ぶんレイテンシが膨らみます(/devops/consistency-models/、/devops/consensus-family-tree/)。
active-passive は書き込み元が常に一つなので因果が単純で、競合解消が要りません。代償は、待機系を縮小運用するとフェイルオーバ時に暖機(warm-up)と容量スケールの時間がかかること、そして平時に待機系がアイドルで資源を遊ばせる点です。「warm standby(縮小して常時稼働)」「pilot light(最小限だけ起動)」「cold standby(停止)」のどれを選ぶかで、RTO とコストが逆相関します。
RPO/RTO とレプリケーション遅延
フェイルオーバ設計は二つの目標値で語られます。**RPO(Recovery Point Objective)**は許容できるデータ損失の量で「何秒ぶんの書き込みまで失ってよいか」、**RTO(Recovery Time Objective)**は許容できる復旧時間で「障害発生から復旧まで何分かけてよいか」です。両者は別物で、別々のメカニズムに支配されます。
RPO ← レプリケーションの同期性で決まる
同期レプリケーション : RPO = 0(コミット時に他リージョンへ反映済み)
非同期レプリケーション : RPO ≈ レプリケーション遅延(lag)ぶん失う
RTO ← 障害検知 + 切替の所要時間で決まる
RTO = 検知時間 + DNS/経路の収束 + 待機系昇格 + 暖機
ここが原理の肝です。同期レプリケーションは書き込みを「他リージョンへ届いて確認が返るまで」コミット完了とみなさないため、RPO はゼロに近づきますが、毎回の書き込みにリージョン間 RTT が上乗せされます。東京・大阪なら数ミリ秒で済んでも、大陸をまたぐと書き込みごとに100ミリ秒級の遅延が乗り、スループットも往復で律速されます。一方非同期レプリケーションは書き込みをローカルで即コミットし、背後で他リージョンへ流すため低レイテンシですが、未転送ぶん(=レプリケーション遅延に相当するデータ)はフェイルオーバ時に失われます。これが非ゼロ RPO の正体です。
非同期構成の RPO は「平均レプリケーション遅延」ではなく、障害が起きた瞬間の遅延で決まります。書き込みスパイク中・GC停止中・ネットワーク輻輳中はlagが平時の何倍にも膨らみ、よりによってそういう不安定な時間帯に障害は起きがちです。RPO の見積もりは平均ではなく、ピーク時lagの上限で行うべきです。lag をメトリクスとして常時監視し、閾値超過でアラートする運用が前提になります。
実務では純粋な同期/非同期の二択ではなく、準同期(semi-synchronous)——少なくとも1つのレプリカへ届いたらコミット完了とする——や、書き込みごとに同期/非同期を選べる構成が使われます。重要なのは、RPO=0 を全リージョンで要求するとレイテンシとスループットを犠牲にするというトレードオフを、データの重要度ごとに切り分けることです。
トラフィック切替:DNS とエニーキャスト
障害を検知したら、クライアントのトラフィックを生存リージョンへ向け直さねばなりません。切替手段は大きく DNS ベースとエニーキャストベースに分かれ、収束の速さが決定的に違います。
DNS ベースのフェイルオーバは、ヘルスチェックで障害リージョンを検知し、DNS レコードを生存リージョンの IP へ書き換える方式です。シンプルですが弱点は TTL とキャッシュ滞留にあります。レコードに TTL=60秒 を設定しても、世界中のリゾルバや OS・ブラウザがその TTL を厳密に守る保証はなく、TTL を無視して古い IP をキャッシュし続けるクライアントが現実に存在します。結果、DNS を書き換えても全クライアントが新 IP へ移るまでに TTL を大きく超える時間がかかり、これが RTO の下限を押し上げます。TTL を短くすればキャッシュ滞留は減りますが、DNS クエリ頻度とリゾルバ負荷が増え、ゼロにはできません。
DNSフェイルオーバの切替時間 ≈
ヘルスチェック検知遅延(連続失敗回数 × 間隔)
+ DNSレコード伝播
+ クライアント側キャッシュのTTL満了(最悪 TTL を超過)
エニーキャストは、同一 IP アドレスを複数リージョンから BGP で広告し、ネットワークが各クライアントを**最も近い(経路的に最短の)**リージョンへ自動的に導く方式です。あるリージョンが落ちて経路広告を止めれば、BGP の経路再収束によってトラフィックは自動で他リージョンへ流れます。DNS のようなクライアント側キャッシュ問題がなく、収束はネットワーク層で起きるため一般に高速です。ただしエニーキャストは「どのリージョンへ着くか」を経路が決めるため、TCP コネクション中に経路が変わると接続が切れること、ステートフルな処理の固定化が難しいこと、運用に BGP/ネットワークの制御が要ることが課題です。実務では「エニーキャストで入口(エッジ)を高速収束させ、内部のステート層は別途レプリケーション」という層分けが定石です。
ヘルスチェックとスプリットブレイン回避
フェイルオーバの引き金はヘルスチェックですが、ここに最大の落とし穴があります。ヘルスチェックは『リージョンが死んだ』のか『リージョンが見えないだけ』なのかを区別できない——これが分散システムの根本問題です。ネットワーク分断が起きると、各リージョンは「相手が落ちた」と誤認し、両方が自分をアクティブだと思い込んで同時に書き込みを受け付ける。これがスプリットブレインで、二つの分岐したデータが生まれ、再統合は極めて困難になります(/devops/leader-election-split-brain/)。
正常 : A=active, B=passive、AがBへレプリケーション
分断発生 : AとBが互いに不達。BはAを「死んだ」と判定
誤フェイル : Bも自分をactiveへ昇格 → A,Bが両方書込を受付
分断解消後 : A,Bに非互換な更新が並存 → どちらを正にもできない
スプリットブレインを防ぐ原理は、『誰がアクティブか』を一意に決める仲裁機構を分断に耐える形で置くことです。
- 過半数(クォーラム)判定:奇数個(典型は3)のリージョン/ウィットネスで多数決を取り、過半を得た側だけがアクティブを名乗れる。分断された少数側は自らアクティブ化を諦める。少数側が書き込みを受け付けない以上、二重昇格は起きません。第三のリージョンや軽量なウィットネス(tiebreaker)を置く理由がこれです。
- フェンシング(STONITH):昇格する側が、旧アクティブを確実に無力化してから引き継ぐ。共有ストレージのアクセス権剥奪やフェンシングトークンで、古いリーダーの書き込みを後から拒否できるようにする。
- リース(lease)と単調トークン:アクティブ権を有効期限付きのリースとして付与し、単調増加するエポック番号を添える。古いエポックの書き込みは下流で拒否されるため、リース失効に気づかない旧アクティブが暴走しても害を及ぼせません。
自動フェイルオーバは RTO を縮めますが、誤検知(false positive)に弱い。一時的なネットワーク瞬断やヘルスチェック経路だけの障害で誤って切替えると、健全なアクティブ系を不要に降格させ、かえって可用性を落とします。だからヘルスチェックには連続失敗回数のしきい値と複数の独立した観測点(複数地域から叩く)を持たせ、ヒステリシスで瞬断を吸収します。それでも分断時の安全側の振る舞いは『迷ったら昇格しない』。クォーラムを失った側は書き込みを止める設計が、データ分岐より一時的な書き込み不能を選ぶという正しいトレードオフです(/devops/distributed-locking/)。
設計をつなぐ実務原則
各部品は独立に最適化できません。RPO を厳しくすれば同期レプリケーションでレイテンシが増え、RTO を縮めようと自動切替を攻めれば誤検知でスプリットブレインを招きます。DNS TTL を短くすればキャッシュ滞留は減るが完全には消えない。これらは互いにトレードオフの関係にあります。
- フェイルオーバは冪等に設計する:切替の途中で再送・重複が必ず起き、両系をまたいだリクエストの二重処理が起きうる。受け側を冪等にしておく(/devops/timeout-deadline-propagation/ のデッドライン伝播と併せ、再送が増幅しない構造に)。
- フェイルバックも設計対象:障害リージョンが復旧したとき、溜まった差分を安全に取り込み、再びアクティブへ戻す手順を事前に用意する。フェイルオーバだけ作ってフェイルバックを忘れると、復旧後に二度目のスプリットブレインを招く。
- 定期的に実地で切替える(game day):使われないフェイルオーバは壊れている。レプリケーション遅延、DNS 収束、待機系の暖機が想定どおりかは、実際に切り替えて初めて分かる。エラーバジェットの範囲で計画的に検証する(/devops/sre-slo/)。
RPO と RTO の混同は頻出の誤り。RPO はデータ損失量でレプリケーションの同期性が、RTO は復旧時間で検知+切替の速さが支配する、と即答できること。非同期レプリケーションの RPO は障害時のlagで決まる。スプリットブレインの本質は『見えない=死んだ』の区別不能で、回避策はクォーラム・フェンシング・単調エポックの三つ。DNS フェイルオーバの遅さの正体はクライアント側 TTL キャッシュ滞留、エニーキャストは BGP 経路収束で速いが TCP 接続継続が難点——この対比を押さえておくこと。
まとめ
- active-active は全リージョンで処理し低レイテンシ・高可用だが書き込み競合の解消(リージョン分割・CRDT 等)が必須。active-passive は単一書込元で単純だが切替時間と待機資源のコストを払う。
- RPO はレプリケーションの同期性が決める(同期=0、非同期=障害時lagぶん損失)。RTO は検知+切替+暖機の合計が決める。両者は別メカニズムで、同期レプリケーションは RPO を縮める代わりにリージョン間 RTT をレイテンシに乗せる。
- 切替は DNS(TTL とクライアントキャッシュ滞留が収束を遅らせる)か エニーキャスト(BGP 経路収束で高速だが TCP 継続が難点)。
- スプリットブレインの本質は『見えない=死んだ』を区別できないこと。クォーラム過半数判定・フェンシング・単調エポックトークンで二重アクティブ化を構造的に封じ、迷ったら昇格しない安全側へ倒す。
- フェイルオーバは冪等に設計し、フェイルバック手順を用意し、game day で実地検証する。使われないフェイルオーバは壊れている。
DevOps/インフラ Article
マルチリージョン構成とフェイルオーバ設計を実務で読む
TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。
解決すること
マルチリージョン
比較で見る軸
難易度: advanced / カテゴリ: DevOps/インフラ / タグ数: 6
導入後に効く点
RPO(許容データ損失)はレプリケーションの同期性で、RTO(許容復旧時間)は障害検知+切替の遅さで決まる。非同期レプリケーションはレプリケーション遅延ぶんのデータをフェイルオーバで失う。
先に潰すリスク
用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。
- 難易度
- advanced
- カテゴリ
- DevOps/インフラ
- タグ数
- 6
判断チェックリスト
- 自社の用途が「マルチリージョン / フェイルオーバ」に近いか確認する。
- 強みである「active-activeは全リージョンが本番トラフィックを捌き高可用・低レイテンシだが書き込み競合の解消が要る。active-passiveは待機系へ切替えるだけで単純だが切替時間と待機資源のコストを払う。」が本当に評価軸になるか確認する。
- 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
- 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
- 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
- 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。