HAトポロジの選定で最初に問うべきは「Active-ActiveかActive-Standbyか」という二択ではなく、「何を守るために二重化するのか」という目的の定義です。目的が曖昧なまま構成を決めると、フェイルオーバーが本番で動かなかったり、整合性を保てない設計が出来上がったりします。本記事では、構成の選定判断に必要な視点と、選択ミスが招く落とし穴を整理します。
「とりあえず二重化」でフェイルオーバーが動かない構造
二重化とHAの混同が招く設計ミス
サーバーを2台並べることと、高可用性(HA)を実現することはまったく別の話です。現場では「予備機を用意したからHAになっている」と思い込んだまま設計を進め、本番障害が発生した瞬間に切り替えが動かないという事態が繰り返されています。二重化は「冗長性を持たせる構成」であり、HAはその冗長性を「自動検知・自動判断・自動切替・継続稼働」という仕組みに昇華させたものです。この区別を曖昧にすると、ヘルスチェックの設計が抜け落ちたり、フェイルオーバー後のVIPアドレス引き継ぎを誰も担当していなかったりします。
フェイルオーバーが「絵に描いた餅」になる典型パターン
構築を担当した担当者が後から振り返ると、「VIPアドレスの引き継ぎは設計したが、アプリケーション側の接続先が固定IPのままで、切り替え後も旧ノードを参照し続けた」という話をよく聞きます。HAクラスターとアプリケーション層の間にある「接続の再解決」を設計から省略したことが原因です。クラスター側が正しく動作しても、アプリが旧ノードを向き続ければサービスは回復しません。
同様に、Active-Standby構成でStandbyノードへのレプリケーションを定期的に確認しないと、切り替えが走ったときにデータが過去の状態に戻ることもあります。ある案件では、レプリケーション遅延が24時間以上に達した状態でフェイルオーバーが発生し、障害そのものよりも切り替え後のデータ不整合の収拾に3倍以上の工数がかかりました。二重化の落とし穴は構成の外側ではなく、レプリケーションの状態管理という地味な日常運用の中に潜んでいます。
設計前に問うべき4つの前提条件
フェイルオーバーを本番で機能させるには、「検知・判断・切替・通知」という4ステップが設計に含まれていなければなりません。どれかひとつ欠けても本番では動きません。特に「判断」のステップ、つまりノード障害を誰が・どのロジックで確定するかを明示しないまま進めると、誤検知による意図しない切り替えや、反対に切り替えの遅延が生じます。トポロジの種類を決める前に、この4ステップを設計書に書き出す作業が先です。
Active-ActiveとActive-Standbyの向き不向きの違い
Active-Activeが真価を発揮する条件
Active-Active構成は、複数のノードが同時にリクエストを処理します。水平スケールと高可用性を同時に実現できる点が強みですが、全ノードが書き込みを受け付けるときのデータ整合性管理が設計の核心です。この構成が機能しやすいのは、ステートレスなアプリケーション層、またはセッション情報を外部ストアに委託できる設計の場合です。Webフロントエンドのように「どのノードが処理しても結果が同じ」であれば、Active-Activeは素直に機能します。一方、書き込み処理のように「どのノードが書いたかで結果が変わる」ロジックには、追加の同期コストと整合性設計が伴います。
Active-Standbyが適切な場面
Active-Standby構成では、Activeノードだけがリクエストを処理し、StandbyはReplicaとして待機します。切り替え時にStandbyがActiveの役割を引き継ぐため、設計がシンプルになりやすく、整合性の管理もActive-Activeに比べて容易です。RDBMSのプライマリ・レプリカ構成はその典型で、プライマリへの書き込みをレプリカに伝播させることでフェイルオーバー後の整合性を保ちます。シングルマスター前提で設計されたミドルウェアや、書き込みの一貫性が求められるデータ層に特に向いています。
「どちらでもよい」という選定が最も危険な理由
システム全体をひとつのトポロジで統一しようとすることが、設計の失敗につながるケースがあります。Webアプリケーションを例に挙げると、フロントエンド層はActive-Active、データベース層はActive-Standbyと、層ごとに最適なトポロジを使い分けるのが現実解です。「全部Active-Active」と決め打ちすると、データ整合性管理のコストがすべての層にかかります。「全部Active-Standby」では、フロントエンドのスループットが単一ノードに縛られます。層ごとに要件を切り分けることが、選定の出発点です。
切替時間・整合性・コスト・実装難度の比較
比較表で見るトレードオフ
| 比較軸 | Active-Active | Active-Standby |
|---|---|---|
| 切替時間(障害時ダウンタイム) | ほぼゼロ(継続処理) | 数秒〜数十秒(VIP移動・昇格処理) |
| データ整合性の管理難度 | 高い(書き込み競合・同期設計が必要) | 低い(Single Writeで競合が少ない) |
| インフラコスト効率 | 高い(全ノードが本番トラフィックを処理) | 低い(Standbyは待機コストが発生) |
| 実装難度 | 高い(状態共有・クォーラム設計が必須) | 中程度(レプリケーション・フェイルオーバー設定) |
| スプリットブレインリスク | 高い(全ノード書き込み構成では深刻) | 中程度(フェンシング設計で低減可能) |
| スケールアウト適性 | 高い(ノード追加でスループット向上) | 低い(Active以外は待機専用) |
表の読み方と判断への接続
この比較表は「どちらが優れているか」を示すものではありません。切替時間を最優先するならActive-Active、整合性管理のシンプルさを優先するならActive-Standbyが有利、というトレードオフを整理したものです。どの軸を優先するかは、SLAで定義された許容ダウンタイムと、アプリケーションが持つ書き込み特性によって決まります。許容ダウンタイムが30秒以内であればActive-Standbyで十分な場合が多く、サービス無停止が絶対条件であればActive-Activeを前提にした状態設計から入ることになります。
状態共有(セッション/データ)をどう設計するか
ステートレス化が最初の選択肢
Active-Active構成を採用するとき、最初に検討すべきはアプリケーションのステートレス化です。セッション情報をノード内部に持たない設計にできれば、どのノードがリクエストを受けても同じ結果を返せます。ステートレス化の手段として一般的なのは、セッション情報をRedisやMemcachedなどのインメモリストアに外出しする方法です。ノード間でセッションをリアルタイム同期するよりも、外部ストア経由で参照・更新するほうが実装がシンプルになり、ノード障害の影響範囲も限定できます。
一方、ステートレス化できないロジックも存在します。ファイルのアップロード処理や長時間トランザクション、WebSocketを使ったコネクション維持などは、特定ノードとの親和性が高く、ステートレス化のコストが高くなります。こうした処理については、スティッキーセッション(特定クライアントを特定ノードに固定するロードバランサーの設定)でカバーするか、その処理だけActive-Standby構成の別クラスターに分離する判断が現実的です。
共有データストアの設計判断
Active-Active構成でデータベース層を共有する場合、書き込みの競合制御が設計の要になります。楽観的ロック(バージョン番号で競合を検出して後から解決)と悲観的ロック(書き込み前に排他ロックを取得)のどちらを使うかは、書き込み頻度と競合発生率で判断します。書き込みが少なく競合がほとんど発生しない環境では楽観的ロックが向いており、書き込みが密な環境では悲観的ロックのほうが整合性を保ちやすい場面があります。どちらも設計に入れないまま「とりあえず共有DB」にすると、同時書き込みによるデータ破損が本番で発覚します。
セッション同期のコストと現実的な折り合い
ノード間のセッション同期を選んだ場合、同期の遅延とネットワーク帯域の両方がコストになります。10台以上のノード間でリアルタイムにセッション同期しようとすると、同期トラフィックがサービストラフィックを上回るケースも出てきます。現場での折り合いとして多いのは、「セッションストアはRedis Cluster、ノード間の直接同期はしない」という構成です。状態を外部ストアに集約することで、ノードの追加・削除がセッション切断を引き起こさない設計にできます。セッションストア自体の冗長化も、設計に含める必要があります。
スプリットブレインをどう防ぐかの判断(クォーラム)
スプリットブレインが起きる構造
スプリットブレインとは、ネットワーク分断によってクラスターのノードが互いの存在を確認できなくなり、それぞれが「自分がActiveだ」と判断して書き込みを続けてしまう状態です。Active-Active構成でも、Active-Standby構成でも起き得ます。特にActive-Standby構成では、StandbyがActiveの障害を検知して自身を昇格させたとき、旧Activeがまだ稼働していると、2台のActiveが並立します。この状態が続くとデータが二股に分岐し、どちらが正しいかを判断できなくなります。障害の検知を速くするほどスプリットブレインのリスクは上がるため、「速い検知」と「誤検知による誤切替の抑止」はトレードオフの関係にあります。
クォーラム設計の考え方
スプリットブレインを防ぐ基本的な考え方がクォーラム(定足数)です。「全ノードの過半数が合意しなければActiveに昇格しない」というルールを設けることで、分断が起きても多数派グループだけがActiveを維持し、少数派グループは処理を停止します。クォーラムの基本計算式は「(全ノード数 ÷ 2) + 1」です。たとえば5ノード構成なら3ノードの合意がなければ昇格しません。2ノード構成ではクォーラムを成立させられないため、仲裁者(ウィットネスノード)を1台追加して3ノード構成にするか、外部のクォーラムデバイスを用意します。
フェンシングと昇格制御の組み合わせ
クォーラムだけでは不十分な場面もあります。障害ノードがゾンビ状態(生死が不明瞭な状態)で稼働し続けると、クォーラムによって昇格が抑止されても旧Activeがデータを書き続けるリスクが残ります。これを防ぐのがフェンシング(隔離)です。STONITH(Shoot The Other Node In The Head)と呼ばれる手法では、疑わしいノードの電源をIPMIやILOなどの管理インターフェース経由で強制切断します。フェンシングデバイスの具体的な設定はクラスターソフトウェアに委ねるとして、設計フェーズで「どのフェンシング方式を採用するか」を決定しておくことが先決です。この判断を後回しにすると、実装フェーズで構成の整合性が崩れます。
二重化しすぎて運用が複雑化する境界
複雑化のシグナルを見逃す理由
HA構成を重ねるほど、システムは可用性と引き換えに複雑性を獲得します。この複雑化は徐々に進むため、「気づいたときには誰も全体を把握していない」という状態になりがちです。現場でよく聞く話として、「クラスター構成図を書いた担当者が異動し、残ったメンバーが構成を誰も理解していない」というケースがあります。HA構成の複雑化は、障害対応の遅延という形で可用性を毀損します。冗長化によって可用性を高めようとしたはずが、複雑化によって可用性が下がるという逆説が起きます。
HA層を増やすほど障害ドメインが広がる逆説
層をまたいだHA構成は、障害の影響範囲(障害ドメイン)を広げることがあります。たとえば、ロードバランサー層・アプリケーション層・データベース層のそれぞれに別々のクラスター管理ソフトウェアを導入した場合、フェイルオーバーが連鎖するリスクが生まれます。アプリ層の切り替えがDBへの接続を一時的に中断し、DB層のクラスターがそれをノード障害と誤検知して自身のフェイルオーバーを起動するカスケード障害は、HA構成が過剰に複雑化したシステムで実際に発生します。ある構築事例では、HA構成の追加によって設計書のページ数が3倍になり、障害対応のRunbookが50ページを超えたという話も聞きます。Runbookが複雑になるほど、本番障害時の対応速度は落ちます。
「ここまでHA、ここからは諦める」の線引き
すべての層を同じ水準でHAにする必要はありません。SLAが要求する可用性水準を起点に、「どの層の障害がサービス停止を引き起こすか」という依存関係を整理し、影響が大きい層から優先的にHAを適用します。影響が小さい、または復旧コストが低い層については、HA化のコスト(実装・運用・複雑性)と比較した上で、シングル構成のまま障害時は手動対応という判断も合理的です。重要なのは「どこをHAにしないか」を設計として意図的に決め、「HAにしていない」という事実を運用ドキュメントに明示することです。意図しない単一障害点と、意図的に許容した単一障害点は、運用上まったく異なる扱いをする必要があります。
HAトポロジ選定チェックフレーム
以下のチェックリストを活用して、トポロジの選定判断の抜け漏れを洗い出します。「未決定」が3項目以上残る状態でトポロジを確定した場合、本番でのフェイルオーバー不動作リスクが高い状態です。実装フェーズに入る前にこのフレームで設計を点検します。
- 許容ダウンタイムはどの程度か(ゼロ秒・数秒・数十秒・数分)を、SLAに明示しているか
- アプリケーション層のステートレス化が可能か、またはセッション情報を外部ストアに委託できるか
- データベース層の書き込みはシングルマスター前提か、マルチマスター前提かを決定しているか
- 書き込み競合が発生した場合の解決ロジック(楽観的ロック・悲観的ロック)を設計に含めているか
- スプリットブレイン発生時の対処方針(クォーラム構成・フェンシング方式)を決定しているか
- クラスター管理ソフトウェアのフェイルオーバー検知時間と、SLAのダウンタイム上限が整合しているか
- フェイルオーバーのテスト(障害注入テスト)を定期的に実施できる運用体制を確保しているか
- 層ごとに「HAを適用する」「適用しない」の判断を設計書に明示しているか
- 構成を理解・維持できる担当者が継続的に確保できるか(属人化リスクを評価しているか)
- HA構成の変更(ノード追加・削除・ソフトウェア更新)の手順と影響範囲を文書化しているか
このチェックフレームは、Active-ActiveかActive-Standbyかを決めるための二択ツールではありません。目的と要件を先に整理することで、適切なトポロジと、許容できるトレードオフが自然に絞り込まれます。手を動かす実装の詳細は現場のドキュメントや実機検証に委ねるとして、このフレームの段階でどこに線を引くかを設計チームで合意しておくことが、後工程の手戻りを防ぐ最短経路です。
▶ 手を動かして本番まで到達する
その設計判断を、RHEL10の本番環境で手を動かして固めませんか
ここまでの設計判断は、読めば腹に落ちます。ですが「自分の手で本番まで通しきる自信」は、それとは別の話になります。
最大6名の少人数で、構築実務者の到達点まで引き上げます。座学で終わらせず、本番相当の環境で判断を検証する2日間です。
HAトポロジの設計をRHEL10本番で手を動かして固める上級講座へ →
Linuxセミナー上級編(RHEL10)|最大6名の少人数ハンズオン