わずか数秒!RDS Proxy を Aurora 高速フェイルオーバーに利用する
RDS Proxy が GA されたことは記憶に新しいですが、割と「あぁ、Lambda でコネクション問題を解決してくれるやつでしょ?」というイメージが強いので、Lambda などのサーバーレスアーキテクチャを使われていない環境だとあまり注目されてなかったりするでしょうか?
今回は Lambda やコネクション数の課題がない環境でも、RDS Proxy を使うことで簡単に Aurora 高速フェイルオーバーを実装できるんで恩恵ありますよ!という検証を行ったのでご紹介したいと思います。
そもそも RDS Proxy とは
RDS Proxy はその名前のとおり、RDS 向けの DB プロキシです。よく言われるメリットは冒頭で申し上げたとおり Lambda -> RDS のように従来はコネクション数の問題でアンチパターンと言われた構成において、プロキシで RDS へのコネクションを集約することで課題がクリアになるというものです。
このあたりの詳細は岩田の記事を参照いただくのが良いかと思います。
さて、ここからコネクションの集約ではなく、今回の本題である「フェイルオーバー」のメリットにフォーカスしてお伝えしたいと思います。
Aurora 高速フェイルオーバーについて
Aurora は従来の RDS と比較すると随分と早くフェイルオーバーできる印象があるかと思います。公式の情報によればレプリカが構成されている場合、通常 30 秒以内に完了します。
Q: フェイルオーバー中はどのようなことが起き、どのくらいの時間がかかりますか?
A: Amazon Aurora レプリカを同一の、または異なるアベイラビリティーゾーンに作成しておくと、フェイルオーバーが発生した場合、Aurora は DB インスタンスの正規名レコード (CNAME) を切り替えて正常なレプリカを指定します。指定されたレプリカはこれにより新しいプライマリに昇格します。フェイルオーバーは開始から終了まで通常 30 秒以内に完了します。
(引用元:Amazon Aurora のよくある質問)
とはいえ、早い・遅いの認識は提供しているサービスによって異なります。30 秒のダウンタイムでも遅いとされる環境においては数秒でフェイルオーバーしてほしい場合もあります。そのようなときに Aurora では高速フェイルオーバーを利用します。
従来の高速フェイルオーバーと課題
Aurora MySQL の場合、高速フェイルオーバーを実現させる仕組みとしてグローバル変数 innodb_read_only
があります。この innodb_read_only
を利用した高速フェイルオーバー方法としては、概ね以下の 2 パターンです。( Aurora PostgreSQL は、また別の仕組みで高速フェイルオーバーを実現します )
- クライアント側のドライバーで対応(MariaDB Connector/Jなど)
- DB プロキシで対応(ProxySQLなど)
ドライバー対応の課題
クライアント側のドライバーで対応するメリットは追加リソースが必要ないことです。しかし、クライアントが増えるほどに運用とメンテナンスの負荷は高くなります(修正アップデートの対応など)。そのため、フェイルオーバー高速化のための実装をクライアント側に任せることに抵抗を感じるかたも少なくないかも知れません。
DB プロキシ対応の課題
DB プロキシで対応するメリットはクライアント側に手をいれる必要がないことです。基本的に参照先を DNS で管理できていれば、CNAME レコードをプロキシに向けることで切り替えが可能です。
一方で DB プロキシとなるインスタンスが必要となりますので、追加コストが発生します。さらにプロキシが単一障害点とならないように可用性、拡張性、モニタリングなどをユーザー側で管理する必要があります。
(引用元:オープンソースプラットフォームで ProxySQL を使用して、Amazon Aurora クラスターでの SQL の読み取りと書き込みを分割する方法)
アプリケーションサーバーに DB プロキシを相乗りさせて利用することも出来ますが、そうなると「クライアント側のメンテナンスが発生する」という点で、先述のドライバーによる対応と同じ課題が出てきます。
そこで RDS Proxy
RDS Proxy は先述の例でいうと「DB プロキシ対応」に該当しますが、課題であるユーザー管理の部分をまるっとマネージドサービスにお任せすることで課題がクリアになります。
料金
追加コストが発生する点は避けられませんが、基になる DB インスタンスの vCPU あたり $0.018/h
です。仮に db.r5.large(2 vCPU)
のプロキシとして利用する場合、30 日換算で $12.96
です。DB プロキシの運用から開放されることを踏まえて、安い・高いを判断いただくのが良いでしょう。
やってみる
それでは早速、クラスターエンドポイントと RDS Proxy を利用した場合のフェイルオーバー時間を比較してみましょう。
今回の環境
今回は以下の環境で検証しています。
- 東京リージョン
- Aurora
- db.r5.large(レプリカを 2 台追加した 3 台構成)
- 5.7.mysql_aurora.2.08.1
- クライアント
- Amazon Linux 2
- m5.large
- SQL クライアントは以下のとおり
$ mysql --version mysql Ver 15.1 Distrib 5.5.64-MariaDB, for Linux (x86_64) using readline 5.1
SQL クライアント側では TTL の最小化などのチューニングは一切行っておらず yum install mariadb
でインストールしただけの状態で利用しています。
RDS Proxy は以下の記事を参考に作成済みです。
計測方法
Proxy SQLの記事を参考に、以下のスクリプトを実行中に手動フェイルオーバーを実行します。
#! /bin/bash while true do DATETIME=$(date "+%Y-%m-%d %T.%N") (echo "select '${DATETIME}', now(3), @@hostname, @@innodb_read_only;" | mysql -udbuser -pdbpassword -h 各エンドポイント -s) & sleep 0.5 done
以下のようなレスポンスが返ります。最終フィールドが innodb_read_only
になっており 0
は writer
、1
ならば reader
という判断になります。
2020-08-25 04:28:42.194083284 2020-08-25 04:28:42.211 ip-10-7-2-92 0
フェイルオーバー時間
フェイルオーバーによる切断開始から、再度 writer
ノードからの応答が安定(継続的に innodb_read_only = 0
から応答)したタイミングまでをフェイルオーバー時間としています。
計測結果
5 回のフェイルオーバーテストによる実測値は以下のとおりです。sleep が 0.5 秒なので、ざっくり計測である点はご了承ください。平均値をとるのに 5 回では少ないと思いますので、あくまで参考値程度にお考えください。
リーダーエンドポイントついては、フェイルオーバー直後は writer
と reader
が入り混じって応答がありましたので、ひとまず writer
でもレスポンスが返ってきた時間と、reader
からの応答が安定(継続的に innodb_read_only = 1
から応答)したタイミングを括弧( )
の時間で記載しています。
対象 | 1回目 | 2回目 | 3回目 | 4回目 | 5回目 | 平均値 |
---|---|---|---|---|---|---|
クラスターエンドポイント(秒) | 48.0 | 15.0 | 15.0 | 11.0 | 9.0 | 19.6 |
RDS Proxy(秒) | 0.5 | 0.5 | 1.5 | 1.5 | 2.0 | 1.2 |
リーダーエンドポイント(秒) | 8.0 (50.0) |
6.5 (42.0) |
10.0 (51.0) |
11.5 (305.0} |
8.0 (54.0) |
8.8 (100.4) |
RDS Proxy への接続ログ
1回目、2回目は 0.5
秒としていますが、sleep が 0.5
だと切れ目なく接続できてしまったので、実際には 0.5 未満
ということですね。
$ ./test.sh (中略) 2020-08-25 04:28:42.194083284 2020-08-25 04:28:42.211 ip-10-7-2-92 0 2020-08-25 04:28:42.696020168 2020-08-25 04:28:42.737 ip-10-7-2-92 0 2020-08-25 04:28:43.197867170 2020-08-25 04:28:44.272 ip-10-7-1-87 0 <-- ここで切り替わっている 2020-08-25 04:28:43.699713439 2020-08-25 04:28:44.273 ip-10-7-1-87 0 2020-08-25 04:28:44.201673281 2020-08-25 04:28:44.728 ip-10-7-1-87 0
クラスターエンドポイントへの接続ログ
クラスターエンドポイントの場合、概ね 10
秒以内に再接続されるものの、切り替え直後は writer
と reader
を返すようで、ふらふらと安定しません。先の表では、このふらふらが落ち着いた最初の時間をフェイルオーバー完了時間として記載しています。
2020-08-25 04:28:41.977532219 2020-08-25 04:28:41.997 ip-10-7-2-92 0 2020-08-25 04:28:42.479412087 2020-08-25 04:28:42.496 ip-10-7-2-92 0 ERROR 2013 (HY000): Lost connection to MySQL server at 'reading initial communication packet', system error: 104 ERROR 2003 (HY000): Can't connect to MySQL server on 'database.cluster-czaiwhovvutn.ap-northeast-1.rds.amazonaws.com' (111) ERROR 2003 (HY000): Can't connect to MySQL server on 'database.cluster-czaiwhovvutn.ap-northeast-1.rds.amazonaws.com' (111) ERROR 2003 (HY000): Can't connect to MySQL server on 'database.cluster-czaiwhovvutn.ap-northeast-1.rds.amazonaws.com' (111) ERROR 2003 (HY000): Can't connect to MySQL server on 'database.cluster-czaiwhovvutn.ap-northeast-1.rds.amazonaws.com' (111) ERROR 2003 (HY000): Can't connect to MySQL server on 'database.cluster-czaiwhovvutn.ap-northeast-1.rds.amazonaws.com' (111) ERROR 2003 (HY000): Can't connect to MySQL server on 'database.cluster-czaiwhovvutn.ap-northeast-1.rds.amazonaws.com' (111) ERROR 2003 (HY000): Can't connect to MySQL server on 'database.cluster-czaiwhovvutn.ap-northeast-1.rds.amazonaws.com' (111) ERROR 2003 (HY000): Can't connect to MySQL server on 'database.cluster-czaiwhovvutn.ap-northeast-1.rds.amazonaws.com' (111) ERROR 2003 (HY000): Can't connect to MySQL server on 'database.cluster-czaiwhovvutn.ap-northeast-1.rds.amazonaws.com' (111) ERROR 2003 (HY000): Can't connect to MySQL server on 'database.cluster-czaiwhovvutn.ap-northeast-1.rds.amazonaws.com' (111) ERROR 2003 (HY000): Can't connect to MySQL server on 'database.cluster-czaiwhovvutn.ap-northeast-1.rds.amazonaws.com' (111) ERROR 2003 (HY000): Can't connect to MySQL server on 'database.cluster-czaiwhovvutn.ap-northeast-1.rds.amazonaws.com' (111) 2020-08-25 04:28:49.505833236 2020-08-25 04:28:49.521 ip-10-7-1-87 0 2020-08-25 04:28:50.007785756 2020-08-25 04:28:50.055 ip-10-7-1-87 0 2020-08-25 04:28:50.509662450 2020-08-25 04:28:50.550 ip-10-7-1-87 0 2020-08-25 04:28:51.011514856 2020-08-25 04:28:51.018 ip-10-7-1-87 0 2020-08-25 04:28:51.513480124 2020-08-25 04:28:51.529 ip-10-7-1-87 0 2020-08-25 04:28:52.015351001 2020-08-25 04:28:52.022 ip-10-7-1-87 0 2020-08-25 04:28:52.517243413 2020-08-25 04:28:52.532 ip-10-7-1-87 0 2020-08-25 04:28:53.019198023 2020-08-25 04:28:53.037 ip-10-7-2-92 1 2020-08-25 04:28:53.521108088 2020-08-25 04:28:53.545 ip-10-7-2-92 1 2020-08-25 04:28:54.022979099 2020-08-25 04:28:54.041 ip-10-7-2-92 1 2020-08-25 04:28:54.524963681 2020-08-25 04:28:54.544 ip-10-7-2-92 1 2020-08-25 04:28:55.026832836 2020-08-25 04:28:55.043 ip-10-7-2-92 1 2020-08-25 04:28:55.528693775 2020-08-25 04:28:55.544 ip-10-7-2-92 1 2020-08-25 04:28:56.030545625 2020-08-25 04:28:56.049 ip-10-7-1-87 0 2020-08-25 04:28:56.532439063 2020-08-25 04:28:56.577 ip-10-7-1-87 0 2020-08-25 04:28:57.034317461 2020-08-25 04:28:57.051 ip-10-7-2-92 1 2020-08-25 04:28:57.536183575 2020-08-25 04:28:57.554 ip-10-7-2-92 1
このようにして見ると RDS Proxy のフェイルオーバーが本当にキレイで優秀であることがわかります。
RDS Proxy の注意点
「RDS Proxy えぇやん!」
と思っていただけたならば幸いです。
が、制約事項もございますのであらかじめご確認のうえでご検討ください。以下、一例を記載しています。詳細はリンクを参照ください。
サポートエンジン
RDS Proxy に対応している DB エンジンは Aurora を含めて MySQL
と PostgreSQL
のみです。
- MySQL は
5.6
,5.7
をサポート(8.0
は非対応) - PostgreSQL は
10
,11
,11.5
をサポート
writer へのアクセスのみ
RDS Proxy を介したアクセスは writer
インスタンスで処理されます。執筆時点においてリーダーエンドポイントはサポートされていませんので、read
中心のアクセスはリーダーエンドポイントを直接利用してください。
RDS Proxy の listen ポートは固定
RDS Proxy の listen ポートは MySQL: 3306
, PostgreSQL: 5432
固定です
さいごに
RDS Proxy は Lambda などにおけるコネクション数問題の救世主的に語られがちで、「サーバーレス使ってないんで興味ないすわ」とスルーされていた方も少なくないのではないでしょうか。
今回、コネクション数以外の観点で RDS Proxy の有用性をご紹介したく、高速フェイルオーバーを取りあげました。従来だと高速フェイルオーバーの導入はちょと面倒でしたが、RDS Proxy を利用することで非常に簡単に実装できます。
もし、Aurora のフェイルオーバー時間短縮にお悩みであれば、ご検討されてみてはいかがでしょうか。
そして、「めっちゃ便利なので、是非、リーダーエンドポイントのサポートも!!何卒、なにとぞっ!」と AWS さんにフィードバックを!(個人の感想です)
以上!大阪オフィスの丸毛(@marumo1981)でした!