こんにちは。テクニカルサポート課の森本です。
Auroraをライター/リーダー構成で使用している時、ライターに不具合あった場合にフェイルオーバーするのはわかるんだけど、リーダーに不具合あった場合はどうなるの?と聞かれることがあったので検証してみました。
Auroraのエンドポイントについておさらい
Aurora のクラスターエンドポイントやライターエンドポイントは、CNAME レコード によって各インスタンスエンドポイントを指します。
$ aws rds describe-db-clusters --db-cluster-identifier test "DBClusterMembers": [ { "DBInstanceIdentifier": "reader", "IsClusterWriter": false, "DBClusterParameterGroupStatus": "in-sync", "PromotionTier": 1 }, { "DBInstanceIdentifier": "writer", "IsClusterWriter": true, "DBClusterParameterGroupStatus": "in-sync", "PromotionTier": 1 } ],
上の例では、writerという識別子のDBインスタンスがライターインスタンス、readerという識別子のDBインスタンスがリーダーインスタンスです。
$ dig test.cluster-xxx.ap-northeast-1.rds.amazonaws.com ... ;; ANSWER SECTION: test.cluster-xxx.ap-northeast-1.rds.amazonaws.com. 5 IN CNAME writer.xxx.ap-northeast-1.rds.amazonaws.com. writer.xxx.ap-northeast-1.rds.amazonaws.com. 5 IN A 10.0.4.239 ...
$ dig test.cluster-ro-xxx.ap-northeast-1.rds.amazonaws.com ... ;; ANSWER SECTION: test.cluster-ro-xxx.ap-northeast-1.rds.amazonaws.com. 1 IN CNAME reader.xxx.ap-northeast-1.rds.amazonaws.com. reader.xxx.ap-northeast-1.rds.amazonaws.com. 5 IN A 10.0.3.221 ...
クラスターエンドポイントはライターインスタンスに、リーダーエンドポイントはリーダーインスタンスにそれぞれ関連づけられています。 また、リーダーエンドポイントの動作は以下のドキュメントのとおりです。
リーダーエンドポイントは、Aurora DB クラスター内の利用可能な Aurora レプリカへの接続を分散します。個別のクエリを分散するわけではありません。各クエリをバランスして DB クラスターの読み取りワークロードを分散する場合は、クエリごとにリーダーエンドポイントへの新しい接続を開きます。 クラスターにプライマリインスタンスのみが含まれていて、Aurora レプリカが含まれていない場合、リーダーエンドポイントはプライマリインスタンスに接続します。その場合、このエンドポイントを介して書き込みオペレーションを実行できます。
Amazon Aurora 接続管理 - Amazon Aurora
つまり、ライター1台+リーダー1台構成でリーダーインスタンスが使用不可になった場合、リーダーエンドポイントはライターインスタンスに接続されることが期待されます。
検証
今回は Aurora MySQL を使用して検証を行います。
CNAMEレコードと実際の接続を確認するため、以下のようなワンライナーを処置中にリーダーインスタンスの再起動を実施します。 Aurora MySQLの場合、select @@innodb_read_only; の実行結果が1の場合はリーダーインスタンスに、0の場合はライターインスタンスに接続されていることを示します。
#CNAME確認用 for i in `seq 1 600` ; do date;dig +noall +ans test.cluster-ro-xxx.ap-northeast-1.rds.amazonaws.com >> ./dig.txt ; sleep 1 ; done #リーダーエンドポイント用 for i in `seq 1 600` ; do mysql -h test.cluster-ro-xxx.ap-northeast-1.rds.amazonaws.com -u admin -pxxx -e "select @@innodb_read_only,now();" >> ./endpointtest.txt ; sleep 1 ; done
リーダーインスタンス再起動
$ aws rds reboot-db-instance --db-instance-identifier reader
CloudTrailから実行時間を確認(UTC)(ここで不健全な時間に検証していたことがバレます)
... "eventTime": "2024-08-15T14:33:10Z", "eventSource": "rds.amazonaws.com", "eventName": "RebootDBInstance", ...
RDS イベント(UTC)
$ aws rds describe-events --region ap-northeast-1 --source-type db-instance --source-identifier reader ... { "SourceIdentifier": "reader", "SourceType": "db-instance", "Message": "DB instance shutdown", "EventCategories": [ "availability" ], "Date": "2024-08-15T14:34:21.865000+00:00", "SourceArn": "arn:aws:rds:ap-northeast-1:000000000000:db:reader" }, { "SourceIdentifier": "reader", "SourceType": "db-instance", "Message": "DB instance restarted", "EventCategories": [ "availability" ], "Date": "2024-08-15T14:34:26.778000+00:00", "SourceArn": "arn:aws:rds:ap-northeast-1:000000000000:db:reader" } ...
CNAMEの切り替わり時間(JST)
$ cat dig.txt ... Thu Aug 15 23:33:51 JST 2024 test.cluster-ro-xxx.ap-northeast-1.rds.amazonaws.com. 1 IN CNAME reader.xxx.ap-northeast-1.rds.amazonaws.com. reader.xxx.ap-northeast-1.rds.amazonaws.com. 5 IN A 10.0.3.221 Thu Aug 15 23:33:52 JST 2024 test.cluster-ro-xxx.ap-northeast-1.rds.amazonaws.com. 1 IN CNAME writer.xxx.ap-northeast-1.rds.amazonaws.com. writer.xxx.ap-northeast-1.rds.amazonaws.com. 5 IN A 10.0.4.239 ... Thu Aug 15 23:35:34 JST 2024 test.cluster-ro-xxx.ap-northeast-1.rds.amazonaws.com. 1 IN CNAME writer.xxx.ap-northeast-1.rds.amazonaws.com. writer.xxx.ap-northeast-1.rds.amazonaws.com. 5 IN A 10.0.4.239 Thu Aug 15 23:35:36 JST 2024 test.cluster-ro-xxx.ap-northeast-1.rds.amazonaws.com. 1 IN CNAME reader.xxx.ap-northeast-1.rds.amazonaws.com. reader.xxx.ap-northeast-1.rds.amazonaws.com. 5 IN A 10.0.3.221 ...
リーダーエンドポイントの接続先(UTC)
$ cat endpointtext.txt ... @@innodb_read_only now() 1 2024-08-15 14:33:46 @@innodb_read_only now() 0 2024-08-15 14:33:47 ... @@innodb_read_only now() 0 2024-08-15 14:35:26 @@innodb_read_only now() 1 2024-08-15 14:35:27 ...
digコマンドでのCNAME切り替わり時間と、実際の接続で数秒の際はあるものの(TTL関連が原因?)、リーダーエンドポイントを指定していてもリーダーインスタンスが使用不可の場合はライターインスタンスに接続される動作を確認することができました。
まとめ
リーダーエンドポイント配下のリーダーインスタンスが使用不可になった場合、リーダエンドポイントはライターインスタンスに接続される動作を確認することができました。
リーダーインスタンスの再起動や不具合発生時、実行中のクエリ等は終了される可能性はあるものの、再起動中に全くリーダーエンドポイントが使用不可になるわけではないことがお分かりになるかと思います。
今回はリーダーインスタンスが1台のみの場合の検証を行いましたが、リーダーインスタンスが複数台ある場合はライターインスタンスではなく利用可能なリーダーインスタンスに接続されることが期待されます。そのため、突発的な不具合ではなくリーダーインスタンスの手動での再起動を計画されており、再起動中のライターインスタンスの負荷を懸念される場合、再起動前にリーダーインスタンスを追加いただくことでよりリスク回避が可能と考えられます。
この記事がどなたかの参考になれば幸いです。