Amazon Auroraの耐障害性を検証してみました
はじめに
Amazon Auroraは耐障害性に優れていると言われていますが、実際どれくらい優れているのか把握し辛いと思われますので、テストクエリを使って簡単に確認してみました。
内容
構成
- インスタンスはdb.t2.smallのマスター、レプリカの2台構成
- 適当なテーブルに100万件程の空レコードを作成
フェイルオーバー
- 毎秒Selectを行いながら、フェイルオーバーを実行
- 再取得までの時間を計測
- DNSレコードを確認し変化されているかの確認
インスタンス障害挿入クエリ
- 毎秒SELECTを行いながら、障害挿入クエリを実行
- 再取得までの時間を計測
レプリカの障害
- レプリカ障害を10秒間実行
- マスターに新規レコードの挿入
- レプリカで定期的にSelectしながら同期されることの確認
ディスクの輻輳
- DBを数秒間遅延させてINSERT文を実行
- レプリカにて取得
インスタンス障害挿入クエリに関しては、色々と用意されています。
- INSTANCE – Amazon Aurora インスタンスの MySQL 互換データベースのクラッシュがシミュレートされます。
- DISPATCHER – Aurora DB クラスターのマスターインスタンスにあるディスパッチャーのクラッシュがシミュレートされます。ディスパッチャーは Amazon Aurora DB クラスターのクラスターボリュームに対して更新を書き込みます。
- NODE – MySQL 互換データベースと Amazon Aurora インスタンスのディスパッチャーの両方のクラッシュがシミュレートされます。この障害挿入のシミュレーションでは、キャッシュも削除されます。
注意
公式にも記載されていますが、インスタンスの障害挿入クエリでフェイルオーバーは実行されません。
この障害挿入クエリでは、フェイルオーバーが発生しません。フェイルオーバーをテストする場合は、RDS コンソールで DB クラスターの [Failover] インスタンスアクションを選択するか、AWS CLI の failover-db-cluster コマンド、または RDS API の FailoverDBCluster アクションを使用できます。
あくまで公式が用意したテスト用クエリですので、本番運用の際の障害発生時とは挙動が違う可能性が御座いますので参考程度にご覧ください。
テスト実行
フェイルオーバー
selectを毎秒流しながら、コンソールからフェイルオーバーを実行してみます
結果
約7秒程接続が切れてしまいましたが、すぐに復旧。
コンソール画面でもwriterとreaderが切り替わっているのが確認できました。
実行前
実行後
nslookupで確認したところ、前後で変わっています。
変更後には、元レプリカで現マスターのエンドポイントを参照しているので、フェイルオーバーはDNSの切り替えも行なっているのが分かります。
$nslookup test-aurora.cjfv4k8h2ojt.ap-northeast-1.rds.amazonaws.com
Server: 192.168.10.1
Address: 192.168.10.1
Non-authoritative answer:
test-aurora.cjfv4k8h2ojt.ap-northeast-1.rds.amazonaws.com canonical name = ec2-13-115-184-85.ap-northeast-1.compute.amazonaws.com.
Name: ec2-13-115-184-85.ap-northeast-1.compute.amazonaws.com
Address: 13.115.184.85
$nslookup test-aurora-ap-northeast-1c.cjfv4k8h2ojt.ap-northeast-1.rds.amazonaws.com
Server: 192.168.10.1
Address: 192.168.10.1
Non-authoritative answer:
test-aurora-ap-northeast-1c.cjfv4k8h2ojt.ap-northeast-1.rds.amazonaws.com canonical name = ec2-13-112-31-161.ap-northeast-1.compute.amazonaws.com.
Name: ec2-13-112-31-161.ap-northeast-1.compute.amazonaws.com
Address: 13.112.31.161
INSTANCE
クラスタエンドポイントからDBをクラッシュさせるクエリを実行してみます。
ALTER SYSTEM CRASH INSTANCE;
結果
約2秒程接続が出来なかったが、すぐに復旧しました。
コンソールを確認したところ、イベントログにマスタ、レプリカ共に再起動したとの記載がありました。
10月 24 3:02 午後
DB instance restarted
nslookupからエンドポイント(クラスタ、マスタ、レプリカ)を確認しても、実行前と後で何も変わっていないところを見ると、DBの再起動のみ行なったようです。
DISPATCHER
こちらもクラスタエンドポイントからクラッシュさせてみます。
ALTER SYSTEM CRASH DISPATCHER;
こちらは5秒ほどで復旧致しました。
そもそもディスパッチャーとは?と思い公式を見た所、
ディスパッチャーは Amazon Aurora DB クラスターのクラスターボリュームに対して更新を書き込みます。
とのことですので、ディスパッチャーを停止させるとレプリカへの同期が一瞬停止するのではないかと思い試してみましたが、
ディスパッチャーを停止した瞬間、マスタ、レプリカDBが再起動を始めたのでそもそも書き込みが行えませんでした。
NODE
こちらはノードのクラッシュを起こすSQL
ALTER SYSTEM CRASH NODE;
![]()
6秒ほどの切断でした。
こちらもコンソールから確認すると両DBの再起動が掛かっているのが確認できました。
レプリカの障害
10秒間だけレプリカ障害を起こし、その間にマスターへレコードを挿入。
見辛いですが、画面左がマスター、右がレプリカとなっています。
ALTER SYSTEM SIMULATE 100 PERCENT READ REPLICA FAILURE TO ALL FOR INTERVAL 10 SECOND ;
![]()
無事10秒後にレプリカへの同期が完了致しました。
アプリケーションテスト時に利用すれば便利そうですね。ディスクの輻輳
こちらは遅延を発生させるクエリとなります
ALTER SYSTEM SIMULATE 100 PERCENT DISK CONGESTION BETWEEN 5000 AND 6000 MILLISECONDS FOR INTERVAL 6 SECOND;
![]()
書き込みの遅延が発生してから数秒後に完了し、レプリカへの同期が完了していますね。
アプリケーションのテスト時にDBを遅延させてテストを行うという使い方もできそうです。
まとめ
あくまでテスト用クエリですので、本番運用の際の挙動とは違うとは思われますが、障害発生して数秒で復旧は素晴らしいですね。
また、上記のクエリは確認以外にもテスト時に使うことも出来そうです。
フェイルオーバー時にはDNSが切り替わっていますので、実装によっては再度張り直す必要があるかもしれませんので少し注意が必要かもしれません。
いつか機会がありましたらアプリケーションと連携してのテストなどやってみたいと思います。