AWS / SAP-C02

SAP-C02-076 · セクション 09 / タスク 2.4

Application / Database Failover

アプリケーションフェイルオーバー / データベースフェイルオーバー / 正常性検知 / 自動フェイルオーバー / 接続回復 / 障害処理

ゴール

フェイルオーバーを、

障害
↓
別のリソースへ切り替わった
↓
復旧完了

と考えません。

実際には、

障害
↓
正常性を検知
↓
正常な処理先へ切り替え
↓
新しいライター / 処理先が利用可能
↓
接続先の変更へ追従
↓
新しい接続を確立
↓
アプリケーション処理を再開

まで成立して、初めて利用者から見た復旧になります。

特にデータベースでは、自動フェイルオーバーが完了したことと、アプリケーションの接続が復旧したことは別と考えます。

1. アプリケーションとデータベースは別々にフェイルオーバーする

高可用性システムでは、アプリケーション層とデータベース層を同じ障害として扱いません。

例えば、

アプリケーションA
     ↓
Amazon RDS

という構成で、アプリケーションAだけが異常になったとします。

データベースのライターが正常なら、

アプリケーションA異常
↓
正常なアプリケーションBへ切り替え
↓
データベースは
現在の正常なライターを継続利用

でよい場合があります。

逆に、

アプリケーション層
正常

データベースライター
異常

なら、アプリケーション層を切り替える必要はなく、データベース側で新しいライターへのフェイルオーバーと接続回復が必要です。

つまり、

アプリケーションフェイルオーバー
≠
データベースフェイルオーバー

です。両者は独立した状態遷移として考えます。

2. 正常性検知はフェイルオーバーの開始条件

フェイルオーバーは、障害を検出できなければ開始できません。

ただし、

異常を検知した

ことと、

サービスが復旧した

ことは別です。

Amazon RDSのマルチAZ構成では、ライターまたはプライマリに障害が発生すると、Amazon RDSが障害を検出して自動フェイルオーバーを開始できます。

例えばマルチAZ DBクラスターでは、

ライター障害
↓
Amazon RDSが障害を検出
↓
別AZのリーダーへ
自動フェイルオーバー

という流れになります。

したがって、

正常性検知
↓
フェイルオーバー開始

は復旧チェーンの入口です。

その後の、

新しい処理先が利用可能か
接続先が更新されたか
アプリケーションが利用できるか

まで確認します。

3. アプリケーションフェイルオーバーでは「新しい要求の処理先」が変わる

アプリケーション層の一部が利用不能になった場合は、正常なアプリケーション対象へ新しい要求を送れる状態にします。

処理対象A
異常

処理対象B
正常
↓
新しい要求はBへ

ここで重要なのは、アプリケーション層の切り替えだけで、依存するデータベースまで自動的に切り替わるわけではないことです。

正常なアプリケーション対象が正常なデータベース接続を確立できなければ、アプリケーション側だけ切り替わってもサービスは復旧しません。

4. データベースフェイルオーバーでは「ライター変更」と「接続回復」を分ける

データベースフェイルオーバーでは、

旧ライター
↓
利用不能
↓
新しいライター

というロール変更が発生します。

しかし、アプリケーションから見ると、

新しいライターが利用可能

だけでは不十分です。

アプリケーション
↓
接続先を解決
↓
現在のライターへ接続

まで成立する必要があります。

したがって、

ライター変更
+
接続先の更新へ追従
+
接続回復

を一続きで考えます。

5. RDSマルチAZ DBインスタンスでは同じエンドポイント名の向き先が変わる

Amazon RDSマルチAZ DBインスタンスでは、プライマリが利用不能になると、RDSが別AZのスタンバイへ自動フェイルオーバーします。

フェイルオーバー時には、

フェイルオーバー前

同じDBエンドポイント名
↓
旧プライマリ

から、

フェイルオーバー後

同じDBエンドポイント名
↓
新プライマリ

となるよう、RDSがDNSレコードの向き先を変更します。

したがって、アプリケーションでは、

障害前のDBエンドポイント名
↓
フェイルオーバー後に
別名へ設定変更

する設計を前提にしません。

安定したRDSのDBエンドポイント名を使用し、RDS側のロール変更へ追従できることが重要です。

6. 長いDNSキャッシュは接続回復を遅らせる

フェイルオーバー後にDNSレコードが更新されても、アプリケーションや接続プールが古いIPアドレスを長期間キャッシュしていると、

RDS
新ライター準備完了
↓
DNS更新済み

しかし

アプリケーション
↓
古いIPを使用
↓
接続失敗

となる場合があります。

したがって、RDSへ直接接続する場合は、

安定したDBエンドポイントを利用
+
DNSを長期間キャッシュしない
+
失敗した接続を再確立

という設計が必要です。物理IPアドレスを固定するのではなく、DNS変更へ追従できることを判断します。

7. マルチAZ DBクラスターではライターエンドポイントを使う

Amazon RDSマルチAZ DBクラスターでは、

ライター
+
リーダー
+
リーダー

が別々のAZへ配置されます。

ライター障害時には、リーダーの1台が新しいライターへ昇格します。

書き込みアプリケーションでは、現在のライターDBインスタンスのインスタンスエンドポイントへ固定するのではなく、クラスターのライターエンドポイントを使用します。

アプリケーション
↓
ライターエンドポイント
↓
現在のライター

フェイルオーバーすると、

ライターエンドポイント
↓
新しいライター

へ接続先が変わります。

8. エンドポイント名が同じでもDNSキャッシュは残る

マルチAZ DBクラスターでは、フェイルオーバー後もアプリケーションが使用するライターエンドポイント名を維持できます。

ただし、

エンドポイント名
同じ

物理IPアドレス
変更

です。

接続プールなどが古いDNS結果を保持していると、利用不能になったDBインスタンスや、現在は読み取り専用となったDBインスタンスへ接続しようとする可能性があります。

そのため、

ライターエンドポイント
+
DNSキャッシュ更新

を組み合わせて考えます。

9. Auroraのクラスターエンドポイントもライター変更へ追従する

Amazon Auroraでも同じ基本判断を使います。

Auroraのクラスターエンドポイントは現在のプライマリへ接続します。

Aurora
クラスターエンドポイント
↓
現在のプライマリ

プライマリ障害で別インスタンスが昇格すると、

同じクラスターエンドポイント
↓
新しいプライマリ

へ接続先が変わります。

ここでも、エンドポイント名を固定できることと、DNS結果を永久に固定してよいことは同じではありません。

10. RDS Proxyは接続回復をデータベースから分離する

直接接続では、

アプリケーション
↓
DBエンドポイント
↓
DBインスタンス

となります。

RDS Proxyを使用すると、

アプリケーション
↓
RDS Proxy
↓
DBライター

という接続境界を作れます。

データベースライターが利用不能になると、RDS Proxyは新しいプライマリDBインスタンスへ接続を振り向けます。

また、データベースライターを一時的に利用できない間も、RDS Proxyは着信要求をキューへ入れることができます。

そのため、

多数のDB接続
+
フェイルオーバー時の
DNS変更や再接続の影響を
アプリケーションから小さくしたい

という場合にRDS Proxyを評価します。

RDS Proxyはフェイルオーバー中も同じIPアドレスで接続を受け続け、新しいプライマリへ接続を振り向けるため、クライアント側のDNS伝播やローカルDNSキャッシュの影響を抑えられます。

11. RDS Proxyでも実行途中の処理まで成功保証されるわけではない

RDS Proxyによって接続回復の影響を減らせても、

トランザクション実行中
SQL文実行中

の処理まで必ず透過的に完了できるわけではありません。

フェイルオーバー発生時に実行途中だったトランザクションやSQL文の接続は、キャンセルされる場合があります。

したがって、

RDS Proxy
=
フェイルオーバー中の
すべての業務処理が成功

ではありません。アプリケーション側でも、実行途中の処理が失敗した場合を扱える必要があります。

12. Aurora Global Databaseではグローバルライターエンドポイントを評価する

Aurora Global Databaseでリージョン間のスイッチオーバーまたはフェイルオーバーを行う場合は、グローバルライターエンドポイントを利用できます。

アプリケーション
↓
グローバルライターエンドポイント
↓
現在のプライマリリージョン

プライマリリージョンが変わっても、アプリケーションが使用するグローバルライターエンドポイントの値は維持されます。

ただし、実際のDNSの向き先は変更されるため、アプリケーションやネットワーク層で長いDNSキャッシュを持たないことが重要です。

13. 自動フェイルオーバーは「停止時間0秒」ではない

「自動」という言葉を、

無停止

と読み替えません。

現在のAWS公式ドキュメントでは、RDSマルチAZ DBインスタンスのフェイルオーバー時間は通常、

60~120秒

です。大きなトランザクションや長期にわたる復旧処理などによって、さらに長くなる場合があります。

一方、RDSマルチAZ DBクラスターでは通常、

35秒未満

です。こちらも、データベース活動や未適用トランザクションなどの状態に影響されます。

したがって、

自動フェイルオーバー
↓
RTO = 0

ではありません。

14. フェイルオーバー時間と接続回復時間を分ける

利用者から見た復旧時間は、

障害検知
+
新しい処理先の選択
+
DBライター変更
+
DNS / 接続先更新
+
接続再確立
+
処理再開

です。

例えば、

DBフェイルオーバー
30秒

アプリケーションDNSキャッシュ
120秒

なら、データベース自体が30秒で利用可能になっても、アプリケーションの復旧にはさらに時間がかかる可能性があります。

つまり、データベース側のフェイルオーバー時間だけを、利用者から見た復旧時間として扱わないことが重要です。

15. 障害処理では「途中の処理」を考える

フェイルオーバー中には、

新しい接続

だけでなく、

障害発生時点で
実行途中だった処理

も存在します。

例えば、

BEGIN
↓
UPDATE
↓
ライター障害
↓
接続異常

となった場合、アプリケーションは単に、

新ライターへ接続できた

だけではなく、

途中の業務処理を
どう扱うか

を決める必要があります。

RDS Proxyを使用していても、実行途中のトランザクションやSQL文はキャンセルされる場合があります。

したがって、

接続回復
+
途中処理の障害処理

まで設計します。

16. 責任を分けて比較する

段階主な責任
障害の検出正常性検知
アプリケーション対象の切り替え正常なアプリケーション処理先へ新規要求を送る
DBライターの切り替えRDS / Auroraなどの自動フェイルオーバー
安定した接続先DBエンドポイント / ライターエンドポイント
DNS変更への追従DNSキャッシュの更新
接続再確立アプリケーション / 接続プール
接続障害の吸収RDS Proxyなど
実行途中処理の扱いアプリケーションの障害処理

1つの機能ですべてを担当しません。

17. シナリオ1:アプリケーションだけが障害

アプリケーションA
異常

アプリケーションB
正常

Amazon RDS
正常

この場合、

アプリケーションA
↓
新規要求から除外

アプリケーションB
↓
既存の正常なDBライターを利用

とします。DBが正常なのに、アプリケーション障害を理由としてDBまで強制フェイルオーバーする必要はありません。

18. シナリオ2:DBはフェイルオーバーしたがアプリケーションが復旧しない

旧DBライター
障害
↓
RDS自動フェイルオーバー
↓
新DBライター
正常

しかし

アプリケーション
↓
古いIPをキャッシュ
↓
接続失敗

この場合、

さらにDBレプリカを追加

することが中心解決ではありません。

確認するのは、

安定したDBエンドポイント
DNSキャッシュ
接続プール
再接続

です。

19. シナリオ3:フェイルオーバーによる接続影響を小さくしたい

要件:

RDSマルチAZ
+
多数の長時間DB接続
+
アプリケーションへの
フェイルオーバー影響を減らしたい

この場合、

アプリケーション
↓
RDS Proxy
↓
Amazon RDS

を評価できます。

ただし、

RDS Proxy導入
↓
すべてのトランザクションが
無条件に成功

とは判断しません。

20. 混同ポイント

混同正しい判断
アプリケーションがフェイルオーバーすればDBも切り替える障害した層だけ切り替える場合がある
異常検知 = 復旧完了正常性検知はフェイルオーバー開始条件
RDSの自動フェイルオーバー = アプリケーションも完全復旧接続回復まで確認する
フェイルオーバー後はDBエンドポイント名を変更するRDSが同じエンドポイント名のDNS向き先を新プライマリへ変更する
DBの物理IPを固定すれば確実フェイルオーバーでIPが変わるため安定したエンドポイントを使う
マルチAZ DBクラスターでは現在のライターのインスタンスエンドポイントを固定ライターエンドポイントを使用する
DNSが更新されれば古いキャッシュは無視できるクライアントや接続プール側のキャッシュも影響する
RDS Proxyならフェイルオーバー時の全SQLが成功実行途中のトランザクションやSQL文はキャンセルされる場合がある
自動フェイルオーバー = 停止0秒検知・切り替え・接続回復時間がある
DBのフェイルオーバー時間 = 利用者から見た復旧時間アプリケーション接続回復まで含める

21. SAP-C02判断フロー

障害発生
↓
どの層が異常か?
│
├─ アプリケーション層
│    ↓
│  正常なアプリケーション対象へ切り替え
│
└─ データベースライター
     ↓
   正常性を検知
     ↓
   DBフェイルオーバー
     ↓
   新しいライター利用可能
     ↓
アプリケーションの
接続先は追従できるか?
     ↓
安定したエンドポイントを使用
     ↓
DNSキャッシュを更新できるか?
     ↓
接続を回復
     ↓
実行途中処理の失敗を扱う
     ↓
利用者から見て処理可能

まとめ

フェイルオーバーは、

予備リソースがある

だけでは完成しません。

判断順序は、

正常性検知
↓
障害した層を特定
↓
正常な処理先 / ライターへ切り替え
↓
安定したエンドポイントへ追従
↓
DNSキャッシュを更新
↓
接続を回復
↓
途中処理の失敗を扱う
↓
利用者から見た復旧

です。特にデータベースでは、自動フェイルオーバーと接続回復を別の責任として考えることが重要です。

主要AWS公式資料

  • AWS Certified Solutions Architect - Professional 試験ガイド(SAP-C02)
  • Amazon RDS — マルチAZ DBインスタンスのフェイルオーバー
  • Amazon RDS — マルチAZ DBクラスターのフェイルオーバー
  • Amazon RDS — マルチAZ DBクラスターへの接続
  • Amazon RDS — RDS Proxy
  • Amazon RDS — RDS Proxyの概念と用語
  • Amazon RDS — ベストプラクティス
  • Amazon Aurora — クラスターエンドポイント
  • Amazon Aurora Global Database — スイッチオーバー / フェイルオーバー

理解確認

このページの内容を8問で確認します。

理解確認8問へ →