Elasticsearchを中心とした基幹システムにおいて、障害発生時の業務継続性を確保するための効果的な災害復旧(DR)ソリューションが求められています。本記事では、Infini Gateway(旧称:极限网关)を活用し、アプリケーション側の改修を最小限に抑えたまま、データの複製とフェイルオーバーを実現するアーキテクチャについて解説します。
アーキテクチャ概要
本ソリューションの核心は、アプリケーションとElasticsearchクラスタの間にInfini Gatewayを配置することにあります。アプリケーションからの書き込みリクエスト(INSERT/UPDATE/DELETEなど)はゲートウェイを通じてプライマリクラスタへ転送されると同時に、非同期でスタンバイ(復旧用)クラスタへも複製されます。一方、読み取りリクエストは通常通りプライマリクラスタへルーティングされます。アプリケーションは透過的にゲートウェイを利用するため、接続先がElasticsearchであるかのような挙動を維持します。
主なメリット
- 軽量かつ高効率: Go言語で実装されており、バイナリサイズは約10MBと軽量です。外部依存が存在しないため、サーバーへのデプロイが非常に容易です。
- バージョン横断対応: 異なるElasticsearchバージョン間での通信を抽象化・仲介するため、クラスタのバージョンアップ時にアプリケーションコードを修正する必要がなく、移行コストを大幅に削減できます。
- 高可用性設計: 仮想IP(VIP)を用いたアクティブ・スタンバイ構成や、クラスタ構成の自動検知機能が備わっており、ノードの障害検知から自動再試行までを自動化します。
- 柔軟な運用: プライマリ・スタンバイともに読み書きが可能であり、設定ファイルの切り替えやゲートウェイの再起動だけで即座に Switchover(切り替え)と Failback(復旧)を実行できます。
デプロイ手順
1. ダウンロードと展開
対象のOSプラットフォームに合わせてインストールパッケージを取得し、任意のディレクトリへ展開します。
mkdir -p /opt/infini-gateway
tar -xzf gateway-linux-amd64.tar.gz -C /opt/infini-gateway
2. 設定ファイルの作成
ゲートウェイの挙動を定義するために設定ファイル(例: gateway.yml)を作成します。以下は、プライマリクラスタとスタンバイクラスタの接続情報を定義する設定例です。環境に合わせてエンドポイントや認証情報を変更してください。
entryPoints:
- name: es_gateway
port: 8000
protocol: http
flow:
- name: main_flow
filter:
- elasticsearch:
# プライマリクラスタ設定
primary: true
endpoints:
- http://192.168.1.10:9200
username: "admin"
password: "secure_password"
# スタンバイクラスタ設定(非同期レプリケーション)
replica:
endpoints:
- http://192.168.1.20:9200
username: "admin_replica"
password: "secure_password"
buffer_size: 512MB
3. サービスの起動
設定ファイルを読み込んでゲートウェイを起動します。
# フォアグラウンドでの実行(動作確認用)
./gateway-linux-amd64 -config gateway.yml
# バックグラウンドサービスとして登録(systemd等を利用)
./gateway-linux-amd64 -service install
./gateway-linux-amd64 -service start
災害復旧シナリオの検証
ゲートウェイを介した運用において、想定される障害パターンとシステムの挙動を確認します。なお、データの複製は主にBulk APIを通じて行われます。
シナリA:通常運用時
書き込みリクエストはプライマリクラスタで処理され、同時にスタンバイクラスタへ送信されて保存されます。読み取りはプライマリクラスタから返されます。
# ゲートウェイ経由でデータ書き込み
curl -XPOST "http://localhost:8000/logs/_bulk" -u "admin:secure_password" -H "Content-Type: application/x-ndjson" --data-binary $'
{"index":{"_id":"101"}}
{"status":"active", "message":"system normal"}
{"index":{"_id":"102"}}
{"status":"active", "message":"data recorded"}
'
プライマリおよびスタンバイクラスタの両方でデータが確認できます。
シナリオB:プライマリクラスタ障害時
プライマリクラスタを停止した状態を想定します。この場合、書き込みリクエストはエラーとなりますが(厳格な一貫性担保のため)、読み取りリクエストはスタンバイクラスタへ自動転送され、業務を継続できます。
シナリオC:スタンバイクラスタ障害時
スタンバイクラスタを停止した状態を想定します。書き込みリクエストはプライマリクラスタで正常に処理されます。同期先が利用できないため、ゲートウェイはディスク上のキューに書き込み操作を一時的に保存します。スタンバイクラスタ復旧後、キューに蓄積されたデータは自動的に再生され、最終整合性が保証されます。
スイッチオーバー(切り替え)手順
プライマリクラスタの復旧が長引く場合、スタンバイクラスタを新たなプライマリとして昇格させる必要があります。切り替えは非常にシンプルです。
設定ファイルにおいて、以前「スタンバイ」として定義していたクラスタ設定を「プライマリ」へ変更し、以前の「プライマリ」を「スタンバイ」へ変更します。あるいは、あらかじめ設定を入れ替えた予備のゲートウェイインスタンス(ゲートウェイB)を準備しておき、切り替え時に現在のゲートウェイ(ゲートウェイA)を停止し、ゲートウェイBを起動します。これにより、アプリケーションの接続先(VIP)を変更することなく、瞬時に復旧サイトへトラフィックを切り替えられます。
フェイルバック(復旧帰還)と整合性確認
旧プライマリクラスタの修復が完了したら、それを再びスタンバイとして組み込みます。起動後、ゲートウェイは修復期間中に発生した差分データをキューから再生し、データの同期を行います。
Infini Consoleなどの管理ツールを利用すれば、キューのオフセット進捗を監視できます。完全な同期を確認するために、ドキュメント数や内容のチェックサム比較を行う整合性タスクを実行し、データが完全に一致していることを確認してから通常運用に戻ることを推奨します。復旧後は、再び設定を元に戻す(ゲートウェイAを起動し、Bを停止する)ことで、通常の構成へ戻ります。
ゲートウェイ自体の高可用性
ゲートウェイ単体がシングルポイントオブ failure (SPOF) とならないよう、以下の2つのアプローチが推奨されます。
1. VIPによるアクティブ・スタンバイ構成
2台のゲートウェイを仮想IP(VIP)の監視下に配置します。アクティブなゲートウェイに障害が発生した場合、VIPがスタンバイ側へ即座に移行し、接続を引き継ぎます。構成はシンプルですが、同時稼働は1台のみに限られます。
2. ロードバランサ + 分散メッセージキュー構成
より高いスループットが必要な場合、フロントにロードバランサを配置し、複数のゲートウェイインスタンスを並列で稼働させます。書き込みリクエストは分散メッセージキュー(Kafka等)を介して共有され、ゲートウェイをステートレスに拡張可能です。これにより、大規模なトラフィックとフェイルオーバーの両方を柔軟に処理できます。