公式ドキュメントはこの辺りになります。
https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/aurora-replicas-adding.html
AWSのRDSでAuroraを運用していますが、これまでそれほど負荷が高くないことも有り、リードレプリカのインスタンスは利用していませんでした。
これを、ちょっと重たい分析などを行いたいという話が出てきたため、リードレプリカのインスタンスを追加すればできるんじゃないかということで、漠然とした利用イメージはあるものの細かな動作や設定をどうすればいいかわかっていなかったので、確認してみたものです。
一通り動かして確認したものですが、ツールなどを使って厳密に検証を行ったと言えるものではありませんので、もし誤って理解しているような箇所があればご指摘いただけると幸いです。
結論
とにかく、検証結果確認できた結論から。
- 書込み可能なプライマリーインスタンスと、読み込み専用のリードレプリカは、インスタンスタイプは揃える必要はない。プライマリーより大きいリードレプリカ、プライマリーより小さいリードレプリカのどちらも作成が可能。
- エンドポイントは、クラスターのエンドポイントを指定し、個別インスタンスのエンドポイントは使用しない。個別のインスタンスを指定したい場合は、カスタムエンドポイント機能を使う。
- RDSの停止処理は、クラスター単位。リードレプリカを追加して、レプリカのインスタンスのみを停止させるといったことは不可能。
- プライマリーインスタンスに書き込まれた情報は、ほぼリアルタイムでレプリケーションされる。(タイムラグは通常数十ミリ秒単位)よほどシビアにリアルタイム性が追求されるシステムでもない限り、誤差が発生することを意識する必要なし。
- プライマリーインスタンスのDBに読み込みロックが掛かると、リードレプリカのテーブルも読み込み不可となる。
- Fail-over状態は1分程度で復旧。
0.前提
環境は AWS RDS Aurora for Postgres でエンジンバージョンは 10.7
で確認しました。
1.インスタンスタイプについて
検証では、プライマリーインスタンスのタイプを
プライマリーインスタンスタイプ | リードレプリカのインスタンスタイプ |
---|---|
r5.large | t3.medium |
t3.medium | r5.large |
の両方で検証。いずれも問題なく作成できた。
もちろん、両方のサイズを揃えた状態でも問題なし。
2.エンドポイントについて
参考URL
https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/Aurora.Connecting.html#Aurora.Connecting.AuroraPostgreSQL
https://dev.classmethod.jp/cloud/aws/amazon-aurora-custom-endpoints/
AruroraのDBを指定するエンドポイントとしては
- クラスターの書き込み用エンドポイント
- クラスターの読み込み用エンドポイント
- カスタムエンドポイント
- インスタンスエンドポイント
の4種類がある。
この内、インスタンスエンドポイントについては基本的に 利用してはいけない 。
一見、インスタンスのエンドポイントを指定しても正常に動作するように見えるが、フェイルオーバーなどの処理によってロールが変更され、書き込み用インスタンスだったものが読み込み専用になるなど、障害等が発生した際に処理が継続できなくなる恐れがある。このため、必ずクラスターのエンドポイントを指定する。
クラスターのエンドポイントは書き込み用と読み込みようが用意されていて、基本は書き込み用にアクセスできるようになっていればすべての処理が実行可能。
読み込み用のエンドポイントの場合は、リードレプリカが複数ある時、どのインスタンスにアクセスするかは自動的に振り分けられる形になる。
リアルタイム分析など、読み込み専用の処理であれば、読み込み用のエンドポイントを利用することで、書き込み用のプライマリーインスタンスに負荷をかけずに処理することができる。
カスタムエンドポイントは、その組み合わせ。例えばリードレプリカを5台用意しているような場合で、分析で大きな負荷がかかるような処理がある場合、書き込み処理を行うメーンの処理はプライマリー1台と2台のリードレプリカを指定し、残りの3台を分析処理専用に使う、といった処理系の大きさに合わせた組み合わせでインスタンスを効率的に利用することが可能となる。
[未検証情報]
参考URL: https://readouble.com/laravel/6.x/ja/database.html#read-and-write-connections
Laravelを利用する場合は、databaseの設定で、readとwriteのDBを切り分けが可能。
この機能とエンドポイントの指定をうまく組み合わせれば、書き込み処理と読み込み処理の接続先を切り分けることで負荷分散が図れるはず。
3.停止・削除処理
RDSの停止処理は通常のRDSインスタンスと同様に1週間の停止後自動起動となる。
ただし、停止できるのはクラスター単位。インスタンス単位での停止は不可。
追加したリードレプリカの削除は随時任意のタイミングで実施可能。
リードレプリカの作成もダウンタイム無しで任意のタイミングで実施可能。
リードレプリカが存在する状態でプライマリーインスタンスを削除すると、ロールが変更され、リードレプリカのインスタンスがプライマリーインスタンスへと昇格する。
ダウンタイムはほとんどなかった(あったとしてもおそらく切り替わる数秒間程度)。
4.レプリケーション・ロック
レプリケーションにより発生するタイムラグは、概ね20ミリ秒以下(同一A-Z内)。異なるアベイラビリティゾーンの場合でも30ms程度。
ほぼリアルタイム処理と考えて問題なし。
Postgresの LOCK TABLE
機能で確認。
プライマリーインスタンスのテーブルにロックをかけると、クラスターのエンドポイントからも、リードレプリカのエンドポイントからも、該当テーブルを読み込めなくなった。
5.Fail-Over
フェイルオーバーをAWS consoleから実行したところ、ダウンタイムあり。
ただし、1分程度で利用可能な状態に復旧する。実際に障害が発生した際も同様と考えられる。