RDS のフェイルオーバーは何秒で完了するのか - マルチ AZ の切り替えメカニズムと DNS 伝播の裏側
RDS マルチ AZ のフェイルオーバーが 60〜120 秒かかる内訳を、障害検知、DNS レコード更新、接続の再確立の各フェーズに分解し、フェイルオーバー時間を短縮する実践的なテクニックを解説します。
マルチ AZ の基本構造 - プライマリとスタンバイ
RDS マルチ AZ 配置では、プライマリインスタンスとスタンバイインスタンスが異なる AZ に配置されます。プライマリへの書き込みは、同期レプリケーションでスタンバイに複製されます。同期レプリケーションとは、プライマリがトランザクションをコミットする前に、スタンバイへのデータ転送が完了していることを確認する方式です。これにより、フェイルオーバー時にデータ損失が発生しません。スタンバイインスタンスは、通常時はアプリケーションからのリクエストを受け付けません。読み取りトラフィックの分散にはリードレプリカを使用します。スタンバイの役割は、プライマリの障害時に即座に昇格できる状態を維持することです。アプリケーションは、RDS が提供するエンドポイント (CNAME) を使用してデータベースに接続します。このエンドポイントは DNS レコードであり、通常時はプライマリインスタンスの IP アドレスに解決されます。フェイルオーバー時には、この DNS レコードがスタンバイインスタンスの IP アドレスに更新されます。
フェイルオーバーの 3 つのフェーズ
RDS のフェイルオーバーは、3 つのフェーズで構成されます。第 1 フェーズは障害検知です。RDS のモニタリングシステムがプライマリインスタンスの障害を検知するまでに、数秒から数十秒かかります。障害の種類によって検知時間は異なります。インスタンスのクラッシュは数秒で検知されますが、ネットワークの部分的な障害 (パケットロスの増加) は検知に時間がかかります。第 2 フェーズは DNS レコードの更新です。スタンバイインスタンスをプライマリに昇格させ、RDS エンドポイントの DNS レコードをスタンバイの IP アドレスに更新します。DNS レコードの TTL (Time To Live) は通常 5 秒に設定されていますが、アプリケーションやオペレーティングシステムが DNS をキャッシュしている場合、古い IP アドレスに接続し続ける可能性があります。第 3 フェーズは接続の再確立です。アプリケーションが新しいプライマリに接続を確立するまでの時間です。コネクションプールを使用している場合、プール内の古い接続は無効になっているため、新しい接続を作成する必要があります。
60〜120 秒の内訳
AWS の公式ドキュメントでは、RDS マルチ AZ のフェイルオーバー時間は「通常 60〜120 秒」とされています。この時間の内訳を分解すると、障害検知に 5〜30 秒、スタンバイの昇格処理に 10〜30 秒、DNS レコードの更新と伝播に 5〜30 秒、アプリケーションの接続再確立に 5〜30 秒です。フェイルオーバー時間に幅がある理由は、障害の種類とデータベースの状態に依存するためです。未コミットのトランザクションが多い場合、スタンバイの昇格時にリカバリ処理 (ロールバック) が必要になり、時間が長くなります。大きなテーブルに対する DDL 操作 (ALTER TABLE) の実行中にフェイルオーバーが発生すると、リカバリに数分かかることもあります。Aurora のフェイルオーバーは、RDS よりも高速です。Aurora はストレージレイヤーが共有されているため、スタンバイの昇格時にデータのリカバリが不要です。Aurora のフェイルオーバー時間は通常 30 秒以内で、Aurora Serverless v2 ではさらに短縮されます。
フェイルオーバー時間を短縮するテクニック
フェイルオーバーの影響を最小化するための実践的なテクニックがあります。第 1 に、DNS キャッシュの TTL を尊重することです。Java の JVM はデフォルトで DNS を無期限にキャッシュします (networkaddress.cache.ttl=-1)。この設定では、フェイルオーバー後も古い IP アドレスに接続し続けます。JVM の DNS キャッシュ TTL を短く設定 (例: 5〜30 秒) してください。第 2 に、RDS Proxy を使用することです。RDS Proxy はアプリケーションとデータベースの間に配置されるプロキシで、フェイルオーバー時に接続を自動的に新しいプライマリにリダイレクトします。アプリケーションは RDS Proxy のエンドポイントに接続するため、DNS の伝播を待つ必要がありません。RDS Proxy を使用すると、フェイルオーバー時のダウンタイムを最大 66% 短縮できると AWS は報告しています。第 3 に、アプリケーション側のリトライロジックです。フェイルオーバー中の接続エラーに対して、指数バックオフ付きのリトライを実装してください。最初のリトライは 1 秒後、次は 2 秒後、その次は 4 秒後、というように間隔を広げます。
フェイルオーバーのテスト - 本番で慌てないために
フェイルオーバーは、本番環境で初めて経験するものであってはなりません。RDS は、手動でフェイルオーバーをトリガーする機能を提供しています。コンソールの「再起動」オプションで「フェイルオーバーで再起動」にチェックを入れるか、CLI で reboot-db-instance --force-failover を実行します。フェイルオーバーテストで確認すべき項目は 4 つです。第 1 に、アプリケーションが自動的に新しいプライマリに再接続できるか。第 2 に、フェイルオーバー中のリクエストがエラーになった場合、リトライロジックが正しく動作するか。第 3 に、フェイルオーバーの完了までにかかった実際の時間。第 4 に、フェイルオーバー後にデータの整合性が保たれているか。CloudWatch の RDSEventNotification を設定しておけば、フェイルオーバーの開始と完了を SNS で通知できます。フェイルオーバーイベントは CloudTrail にも記録されるため、事後分析に利用できます。RDS の可用性設計を体系的に学ぶには、専門書籍 (Amazon)が参考になります。