フェイルオーバー発動を自動化するかの判断 — DBとLBの切替設計

フェイルオーバーの自動化はRTOを短縮する有力な手段だが、判断なしに有効化すると誤検知やsplit-brainによって障害をむしろ拡大させる。DB層とLB層では切替の影響範囲と復旧コストが大きく異なり、自動・半自動・手動のどこに線を引くかが設計の核心となる。本記事ではDBとLBそれぞれの特性に沿った切替設計の判断軸を整理し、環境ごとの使い分けを示す。

自動フェイルオーバーが危険なケースと有効なケースの判断軸

危険なケース——誤検知とカスケード障害

自動フェイルオーバーが最も危険なのは、ノードが「死んでいるように見える」が「実際には生きている」状態だ。ネットワーク瞬断やCPU高負荷によるヘルスチェック応答遅延がその典型で、LBが正常なバックエンドを切り離し、残存ノードに負荷が集中してドミノ倒しになる。DBでは、書き込みが完了していないトランザクションがある状態で昇格が走ると、データロストと二重書き込みが同時に発生するリスクがある。

よくあるつまずきとして、ヘルスチェックの失敗閾値を低く設定しすぎるケースが挙げられる。失敗1回でフェイルオーバーを発動する設定は、瞬断や負荷の過渡状態で誤検知を引き起こしやすい。フェイルオーバー先のスタンバイが十分ウォームアップされていない場合、切替直後に同様の高負荷が再発してスタンバイまで落ちるカスケード障害に発展しかねない。

有効なケース——ステートレス層とマネージドサービス

一方、ステートレスなアプリサーバーやLBのバックエンドプールにおける自動切替は有効に機能しやすい。セッション情報を持たないノードなら切り離しても即座に他ノードへリクエストを分散でき、誤検知のコストが相対的に小さい。マネージドサービス(RDS Multi-AZやALBのターゲットグループ管理)は内部で冪等な切替機構が実装されており、自前でスクリプトを組むよりも安全に自動化できる。

ステートレス層の自動フェイルオーバーを有効にする際の判断材料は、「切替コストが再接続コストを下回るか」だ。DB接続プールの再初期化や認証セッションの再確立に数十秒を要する構成では、ステートレス層であっても切替に伴うコストが無視できない。アプリ側の接続設定と合わせて設計する必要がある。

DB層とLB層で判断軸が異なる理由

DBとLBでフェイルオーバーの判断軸が異なる最大の理由はステートの有無だ。LBのバックエンド切替はリクエスト単位で判断でき、失敗しても次のリクエストでリトライすれば済む。これに対してDBの切替はトランザクションの整合性、レプリケーション遅延、接続プールの再構築を伴い、切替後の一貫性保証まで含めた設計が必要になる。RTOを優先してDBの自動切替を急ぐほど、RPO(目標復旧時点)が犠牲になりやすい点を設計段階で明示しておくことが重要だ。

ヘルスチェックの間隔と失敗閾値をどう設定するか

間隔×閾値がフェイルオーバー発動時間を決める

ヘルスチェックの設定は「間隔(interval)× 失敗閾値(threshold)= フェイルオーバー発動までの最大時間」という関係で決まる。たとえば間隔10秒・失敗閾値3回なら発動まで最大30秒かかる。この時間を短くしたければ間隔を縮めるか閾値を下げるかだが、どちらも誤検知リスクを上げる。間隔を5秒・閾値を2回にすれば最短10秒で発動する反面、瞬断への感度が高くなりすぎる。環境のネットワーク品質とアプリのSLAを参照して調整することが基本の姿勢だ。

信頼性の高い専用線環境では間隔10〜15秒・閾値3回前後が採用されやすい。公共インターネット経由のヘルスチェックはパケットロスが発生しやすいため、閾値を5回以上に設定してバッファを持たせる構成も有効だ。成功閾値(ヘルシーに戻るまでの連続成功回数)も適切に設定しないと、瞬断のたびに切替と復旧が繰り返されるフラッピングが起きる点も見落としやすい。

DB固有のヘルスチェック設計

DBのヘルスチェックは、ポートへのTCP到達性だけでなく「書き込みロールかどうか」まで確認する設計が望ましい。スタンバイがプロモートされてから実際に書き込み受付状態になるまでに数秒から数十秒のラグがある。TCP疎通だけを確認するヘルスチェックはこのラグを見逃し、プロモート途中のノードにトラフィックを流してしまう。読み取りロールか書き込みロールかを区別するSQLを発行するか、マネージドサービスのエンドポイント機構(RDSのCluster Endpointなど)を活用することが設計判断として重要になる。

LB固有のヘルスチェック設計

ALBやNLBのターゲットグループヘルスチェックは、アプリケーションレイヤーのエンドポイントを用いることが望ましい。単純なTCPチェックはプロセスが起動しているだけで「ヘルシー」と判定するが、アプリ内部のDB接続切れやキャッシュ不整合は検知できない。専用のヘルスチェック用エンドポイントでDB接続確認や依存サービスの疎通確認を含めると、より実態に即した判定が可能になる。ただし、このエンドポイントが重くなりすぎると本番負荷に影響するため、応答時間を200ms以内に収める設計にするのが一般的だ。

RDS Multi-AZとRoute 53フェイルオーバーを組み合わせる設計

RDS Multi-AZの切替特性と接続設計

RDS Multi-AZはAWS側が自動でプライマリからスタンバイへ切り替える。切替所要時間は一般的に60〜120秒程度とされており、この間DBへの接続が切断される。アプリ側が自動的に再接続を試みる設計になっているかどうかが、フェイルオーバー体験を大きく左右する。接続プールの再接続リトライ設定を事前に見直しておかないと、フェイルオーバー完了後もアプリが旧エンドポイントに接続し続けるという状況が発生する。

RDS Multi-AZのフェイルオーバーは同一エンドポイント(DNSで解決される)のまま切り替わるため、アプリ側は原則としてエンドポイントURLを変更する必要がない。ただし、アプリサーバーのDNSキャッシュ(OSおよびJVM/ランタイムのキャッシュ)が長すぎる場合に旧IPへの接続が継続されるケースが、よくあるつまずきとして挙げられる。

Route 53フェイルオーバーとの組み合わせ

RDS Multi-AZがDB層の自動切替を担うのに対し、Route 53フェイルオーバーはリージョン全体の障害時や、アプリサーバー・ゲートウェイに障害が発生した場合のDRとして機能する。Route 53のヘルスチェックはHTTP/HTTPS/TCPに対応しており、プライマリリージョンのエンドポイントが応答しなくなった際にセカンダリリージョンへDNSを切り替える設計が一般的だ。TTLを60秒以下に設定することで切替後の伝播時間を短縮できる。

Route 53のヘルスチェックがロードバランサー経由で行われる場合、LBは生きているがDBは落ちているという状態を正確に検知するには、アプリレイヤーのヘルスチェックエンドポイントにDB接続確認を含める設計が必要になる。ヘルスチェックの深さをどこまで持たせるかは、フォールスポジティブとフォールスネガティブのどちらをより回避したいかの判断による。

切替の順序依存とタイムアウト設計

RDS Multi-AZの切替完了よりもRoute 53のフェイルオーバー発動が先に走ると、セカンダリリージョンのアプリがまだ使用可能でないDBに接続しようとする状況が生まれる。切替の「順序」と「タイムアウト設定」を一貫させることが設計の要点だ。Route 53のヘルスチェック失敗検知がDBのMulti-AZ切替完了時間(60〜120秒)より短いタイムアウトに設定されていると、DB復旧前にトラフィックが別リージョンへ流れてしまう。少なくとも180秒以上のタイムアウトを確保したうえでRoute 53を発動させる設計が望ましい。

split-brainをどう検知し防ぐか

split-brainが発生する条件

split-brainとは、プライマリとスタンバイが同時に書き込みを受け付ける状態になることだ。ネットワーク分断によってプライマリとスタンバイ間の通信が途絶えた際に、スタンバイ側がプライマリの死亡を誤検知して自律的にプロモートすることで発生する。実際にはプライマリが生きているまま両ノードが書き込みを受け付け、データの整合性が破壊される。これを修復するためのダウンタイムは、単純なフェイルオーバーよりも大幅に長くなるケースが多い。

quorumベースの検知設計

split-brainの検知には、外部の仲裁者(quorumノードやクラウドAPIを使ったIPの付け替え)を使う手法が有効だ。MySQLのOrchestratorやPostgreSQLのPatroniではquorumベースの合意機構を採用しており、多数決でどちらが真のプライマリかを決定する。クラスターを構成するノードが偶数台になると多数決が成立しにくくなるため、ノード数を奇数台(最小3台)で設計することが基本になる。AWSではRDS Multi-AZがこの仲裁を内部で処理してくれるため、自前のレプリケーション設計と比べてsplit-brainリスクを大幅に軽減できる。

STONITHによる防止と設計判断

自前でHA構成を組む場合、STONITH(Shoot The Other Node In The Head)と呼ばれる強制隔離機構を組み込むことがsplit-brain防止の標準的な手法だ。障害を検知した際に、旧プライマリの電源やネットワークインターフェースをクラウドAPIで強制的に遮断してから新プライマリを昇格させる。この処理は手動では間に合わないためスクリプト化が前提となるが、STONITH自体の誤発火リスクも存在するため、発動条件のチューニングを慎重に行う必要がある。書き込みの整合性を最優先にする場合、フェイルオーバー発動前にプライマリへの書き込みを明示的に禁止するfenceデバイスを挟む設計も有効だ。

フェイルオーバーテストを本番前にどこまでやるか

テストで優先確認すべき2点

フェイルオーバーテストで最優先に確認すべきは「切替後にアプリが自動で再接続できるか」と「データロストが許容範囲に収まるか」の2点だ。切替そのものが成功するかどうかはマネージドサービスに任せるとして、アプリ側の再接続設定が機能するかはコードベースと接続ライブラリの設定に依存するため、必ずテストで確認する。接続プールの設定不備(タイムアウトが長すぎる・接続を使い回す設定になっていないなど)はステージング環境でしか発見できないことが多い。

ステージング環境でのテスト範囲

ステージング環境では少なくとも以下のシナリオを検証することが推奨される。

  1. プライマリDBへの強制停止によるRPO・RTOの実測
  2. ヘルスチェック失敗閾値に達するまでの誤検知シミュレーション(ネットワーク遅延の意図的な挿入)
  3. フェイルオーバー中に実行中のトランザクションがどう処理されるかの確認
  4. LBからの切り離しとアプリの接続再確立のタイムラグ計測
  5. スタンバイ昇格後のレプリケーション再設定が自動で行われるかの確認

ステージングと本番の構成差異(インスタンスサイズ・レプリケーション遅延・ネットワーク帯域)がある場合、ステージングのテスト結果をそのまま本番に適用するのは危険だ。構成差異リストを事前に作成し、どこが違うかを把握した状態でテストを行うことが設計上の前提となる。

本番テストの実施判断

本番でのフェイルオーバーテストは、メンテナンスウィンドウを確保して計画的に実施することが前提だ。RDS Multi-AZの場合、AWSコンソールからRebootによる強制フェイルオーバーが可能で、本番相当の切替時間を実測できる。スタンバイが本番と同等のロールを担えることを確認しないまま本番に初めてフェイルオーバーをかけるのは大きなリスクだ。年1回以上、できれば四半期ごとにテストサイクルを回すことで、設定変更やインスタンスタイプ変更後の挙動を継続的に検証することが望ましい。

手動フェイルオーバー手順書とスクリプト化の使い分け

手順書だけでは機能しない理由

障害対応中の担当者は認知負荷が高い状態にあり、手順書をその場で読み込みながら正確に操作することは難しい。特に深夜帯の対応では判断ミスが起きやすく、手順書に「確認してから実行する」と書いてあっても、焦りからスキップされるケースがよくある。フェイルオーバー手順のうち、「判断が不要で必ず実行する処理」はスクリプト化して自動化し、「状況に応じた判断が必要な分岐点」のみを手順書に残すことが、実際の障害対応で機能する設計だ。

スクリプト化に適した処理の判断基準

スクリプト化に適しているのは冪等性が保証できる処理だ。「LBのターゲットグループからノードAを外す」「RDSのプライマリエンドポイントが切り替わったことを通知する」「Route 53のレコードをセカンダリに向け直す」といった操作は冪等性が高く、繰り返し実行しても副作用が発生しにくい。これらはスクリプト化して運用スクリプト管理ツールで管理する判断が有効だ。

逆にスクリプト化すべきでないのは「DBのプライマリが本当に応答不能かを人間が確認する判断ポイント」や「バックアップが最新状態かどうかをチェックする確認ステップ」だ。これらを自動化すると、誤検知から始まる連鎖的な自動操作が収拾のつかない状態を生み出すリスクがある。

手順書とスクリプトの連携設計

実践的な設計として、手順書の各ステップに「スクリプト実行」と「人間の確認」を明示する形式が有効だ。「Step 1: スクリプトAを実行してプライマリへの書き込みを停止する(自動)→ Step 2: 最終トランザクションがコミット済みかログで確認する(人間)→ Step 3: スクリプトBでスタンバイを昇格させる(自動)」という構造にすることで、ヒューマンエラーが起きにくく、かつ判断が必要なポイントを明示できる。手順書のバージョン管理もGitで行い、インフラ変更時に手順書とスクリプトを同時に更新するフローを定着させることが、長期運用での品質維持につながる。

自動/半自動/手動フェイルオーバーの設計比較

3つの切替方式の特徴と適用場面を以下の表にまとめる。設計選定の際の判断材料として活用できる。

項目 自動フェイルオーバー 半自動フェイルオーバー 手動フェイルオーバー
RTO(目標復旧時間) 最短(数十秒〜2分) 中程度(5〜15分) 長い(30分〜数時間)
誤検知リスク 高い 低〜中(人間が承認) 低い
DB層への適用 マネージドサービス限定で有効 自前HA構成で有効 変更頻度の低い重要DBに有効
LB層への適用 ステートレス層では有効 ステートフルセッションがある場合 通常は不要
split-brainリスク あり(設計で対策必須) 低い(人間が状態確認後に実行) なし
運用担当者の負荷(平時) 低い 中程度 高い
設計・テストコスト 高い(誤検知対策含む) 中程度 低い
主な適用例 RDS Multi-AZ、ALBターゲット切替 Orchestrator+承認フロー、アラートトリガー 重要マスタDB、規制対象データ

設計の出発点として「DB層は保守的に、LBのステートレス層は積極的に自動化する」という方向性が基本になる。自動フェイルオーバーを選ぶ場合は、設計・テストコストが手動の数倍になることを想定した工数計画が必要だ。半自動方式はRTOと安全性のトレードオフが最もバランスよく取れるため、自前でHA構成を組む環境や、誤検知リスクを抑えつつRTOを15分以内に収めたい場合に有力な選択肢となる。

フェイルオーバー方式選定のチェックリスト

方式を選定する際は、以下の項目を確認してから最終判断を行うことが推奨される。

  • RTOの要件が明確になっているか(SLAに基づく数値として合意されているか)
  • RPOの要件が明確になっているか(データロスト許容範囲が定義されているか)
  • ヘルスチェックの誤検知テストを実施済みか
  • アプリ側の再接続設定がフェイルオーバーに対応しているか
  • split-brain発生時の対処フローが決まっているか
  • フェイルオーバー発動後のレプリケーション再設定が自動化されているか
  • テストサイクルのスケジュールが確定しているか(年何回か)
  • 手順書とスクリプトのバージョン管理が統一されているか

▶ 手を動かして本番まで到達する

その設計判断を、RHEL10の本番環境で手を動かして固めませんか

ここまでの設計判断は、読めば腹に落ちます。ですが「自分の手で本番まで通しきる自信」は、それとは別の話になります。

最大6名の少人数で、構築実務者の到達点まで引き上げます。座学で終わらせず、本番相当の環境で判断を検証する2日間です。

フェイルオーバー自動化設計を実装で確かめる上級Linuxハンズオンへ →

Linuxセミナー上級編(RHEL10)|最大6名の少人数ハンズオン