RDSの書き込み転送とは
簡単に言ってしまえば、リーダーインスタンスにきたクエリのうち対応している書き込み系のクエリをライターインスタンスに転送してくれる機能です。
詳細はドキュメントを参照してください。
https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/aurora-global-database-write-forwarding.html
使い所
結局、転送するだけでライターインスタンスで処理されるなら負荷の軽減にはならないし、あまり意味がない機能に見えますが、下記のような用途で使うと便利です。
- 普段は参照系のクエリしか使わないけど、たまに書き込み系のクエリも使いたい
- 書き込みの速度は気にしないけど、書き込み系と参照系のクエリを自動で適切なインスタンスに振り分けたい
実際に使っているケース
私の担当しているシステムで、ある日データベースのCPU使用率が異常に高い状態になりました。調べてみると処理の重たい参照系のクエリが phpMyAdmin から実行されていました。どうやらオペレーターが調査のために実行したようなのですが、利用者に支障が出る可能性があったので、作業を中止してもらいました。
この phpMyAdmin はほんとんどの場合、参照系のクエリしか実行しないのですが、利用者のデータに不具合が起きた場合などに修正のために書き込みクエリも実行します。なので、ライターエンドポイントを設定していました。
上記のトラブル受け、この利用ケースなら書き込み速度は問題にならないし、ほとんどが参照系のクエリのため書き込み転送を有効にしたリーダーエンドポイントで問題ないと判断し、ライターエンドポイントからリーダーエンドポイントにphpMyAdminの向き先を変更しました。
このケースの場合、できるだけライターインスタンスのリソースは利用者のための開けておき、 phpMyAdmin の処理など、運用者の処理はリーダーインスタンスに逃したいというのが目的になります。
設定方法
私が書くよりこちらを参考にしていただく方がわかりやすいと思うので、こちらをご確認ください。
https://dev.classmethod.jp/articles/aurora-local-write-forwarding/
所感
メリット
一番のメリットはリソースを適切に活用できることです。今回の例のシステムだとリーダーインスタンスはフェイルオーバーのためにいるだけで、普段は利用していませんでした。プログラム側でリーダーとライターを使い分けることもできますが、作り込みが大変なので基本的にはライターエンドポイントのみを使っています。
また、エンドポイントを1つにできるので、切り替え忘れによるミスなどを減らせるのも良いと思います。
デメリット
やはり一部のクエリが使えないのは不便です。とくにCreate文が使えないのは不便でTableが作成できないので、日常的にTable作成を行なっている場合は書き込み転送は使えないと思います。
あとは、根本的なスペックアップではないので、書き込みの多い環境ではあまり使い道がないかもしれません。
図解
実際は前段にwebサーバがいてデータベースにアクセスしていますが、簡略化のために省いています。
オペレーターも含めて全員がライターエンドポイントを使っている場合
書き込み系のクエリ、参照系のクエリ問わず、ライターインスタンスのリソースの空き状況を気にしないと、処理負荷が過剰になり、追加の利用者が現れた場合にデータベースの応答に影響が出ます。
状況に応じてオペレーターがライターエンドポイント、リーダーエンドポイントを使い分ける場合
参照系のクエリを実行する場合はリーダーエンドポイントを使うことで、ライターインスタンスのリソースの空き状況を気にしなくてよくなります。
ただし、オペレーターが書き込み系のクエリ、参照系のクエリどちらを使うかを意識しなくてはならず、それによってエンドポイント切り替えが必要になってしまいます。
オペレーターは書き込み転送を有効にした、ライターエンドポイントを使う場合
参照系のクエリを実行する場合はリーダーエンドポイントを使うことで、ライターインスタンスのリソースの空き状況を気にしなくてよくなります。
かつ、書き込み系のクエリを実行する場合もリーダーエンドポイントを使えるので、オペレーターが書き込み系のクエリ、参照系のクエリどちらを使うかを意識しなくて良くなります。
ただし、書き込み系のクエリを実行する場合は上記の二つパターンと同じくライターインスタンスのリソースの空き状況を気にしないといけません。
まとめ
最初にRDSの書き込み転送を見たときは処理負荷が減るわけでもないし、あまり使い道がなさそうと思いましたが、ライターエンドポイントとリーダーエンドポイントを意識して使い分けなくても、参照系のクエリのみをリーダーインスタンスに逃がせるのは割と便利だなと思いました。オペレーターに参照系のクエリならリソースの負荷状況もエンドポイントも気にせず、好きに実行してよいと言えるのは心理的にも楽です。また書き込み系クエリを実行をしたい場合もエンドポイントを気にしなくてよいのは、切り替え忘れなどを防止できる点も良いと思います。