Aurora Global DatabaseのAurora DBクラスターのRDS Proxyを作ってみた

Global Databaseでも出来ることが増えてきた
2023.06.30

RDS ProxyがAurora Global Databaseに対応していた

こんにちは、のんピ(@non____97)です。

皆さんはAurora Global DatabaseでもRDS Proxyを使いたいなと思ったことはありますか? 私はあります。

2023/6/30現在、Aurora DBクラスターのスナップショットのクロスリージョンコピーは増分ではありません。

増分スナップショットコピー

Aurora は、差分スナップショットコピーをサポートしていません。Aurora DB クラスタースナップショットコピーは常にフルコピーです。フルスナップショットコピーには、DB クラスターを復元するために必要なデータやメタデータすべてが含まれます。

DB クラスターのスナップショットのコピー - Amazon Aurora

そのため、RPOによりますがAurora Global Databaseを使った方がAurora DBクラスターのスナップショットのクロスリージョンコピーよりも安くなる場合があります。

一方でAurora Global Databaseは「DBクラスターの停止ができない」や「バックトラックが使えない」、「メジャーアップデート時にカスタムパラメータグループを適用できない」など色々と制約事項があります。

その中にAurora Global DatabseにはRDS Proxyを使用できないというものがありました。

しかし、去年RDS ProxyがAurora Global Databaseをサポートしてくれるようになりました。

ドキュメントもしっかりとしたものがあります。

あまりAurora Global DatabaseでRDS Proxyを使っている記事がなかったので実際に触ってみました。

いきなりまとめ

  • Aurora Global Database自体にRDS Proxyを設定するという訳ではない
    • プライマリクラスターやセカンダリクラスターなど、クラスター単位で作成する
  • プライマリクラスターがあるリージョンからもセカンダリクラスターのRDS Proxyを作成することは可能
  • RDS Proxyを作成するリージョン毎にSecrets Managerのシークレットを用意する必要がある
  • セカンダリクラスターのRDS Proxyの読み取り/書き込みエンドポイントに送信されたリクエストはThe target group doesn't have any associated read/write instancesというエラーになる
    • フェイルオーバーしたら接続先の旧プライマリクラスターのRDS Proxyは読み取りエンドポイントに切り替えよう

やってみた

RDS Proxyの作成

早速やってみます。

検証環境は以下記事で作ったものを使い回します。

Aurora Global Databaseのプライマリクラスターを選択してアクション-RDSプロキシを作成をクリックします。ちなみにAurora Global Database自体にRDS Proxyを設定することはできません。Aurora DBクラスター単位になります。

RDSプロキシの追加

RDS Proxyのパラメーターを指定して、プロキシの作成をクリックします。

ターゲットグループの設定

認証と接続

続けてセカンダリクラスターのRDS Proxyを作成します。

しかし、セカンダリクラスターのあるリージョンからRDS Proxyを作成しようとしましたが、プライマリクラスターがあるリージョンのSecrets Managaerのシークレットは選択できませんでした。

RDS Proxyの作成にはSecrets Managerのシークレットを指定することが必須です。かといって、セカンダリリージョンにも同じ内容のSecrets Managerのシークレットを用意するのも何だか嫌です。

「どうしたものかな」と思い、プライマリクラスターのあるリージョンからRDS Proxy作成画面を眺めていると、セカンダリクラスターを選択できるではありませんか。

セカンダリクラスターの選択も可能

試しに作ってみます。パラメーターはプライマリクラスターのRDS Proxyと全く同じです。

セカンダリクラスターのRDSプロキシーの作成

作成されたプライマリクラスターのRDS Proxyは以下の通りです。

プライマリクラスターのRDS Proxy

セカンダリプライマリクラスターのRDS Proxyは以下の通りです。関連づけられたデータベースとして何も見えていないので上手く認識出来ていない気しかしないですね。

セカンダリクラスターのRDS Proxy

なお、セカンダリリージョンからセカンダリクラスターに登録されているRDS Proxyを確認してもプロキシなしとなっていました。

セカンダリリージョンからセカンダリクラスターの状態を見てもプロキシなし

RDS Proxyへの接続

それではRDS Proxyへの接続をしてみます。

# 認証情報の取得
$ get_secrets_value=$(aws secretsmanager get-secret-value \
    --secret-id AuroraSecret7ACECA7F-EZlGncuM4Jsv \
    --region us-east-1 \
    | jq -r .SecretString)

# 環境変数に埋め込み
$ export PGHOST='db-proxy.proxy-cicjym7lykmq.us-east-1.rds.amazonaws.com'
$ export PGPORT=$(echo "${get_secrets_value}" | jq -r .port)
$ export PGDATABASE=$(echo "${get_secrets_value}" | jq -r .dbname)
$ export PGUSER=$(echo "${get_secrets_value}" | jq -r .username)
$ export PGPASSWORD=$(echo "${get_secrets_value}" | jq -r .password)

$ psql
psql (15.0, server 15.2)
Type "help" for help.

testDB=>

接続できましたね。

接続先は読み取り/書き込みエンドポイントを指定したので書き込みができることも確認しておきましょう。

# 現在のテーブル一覧の確認
testDB=> \dt
         List of relations
 Schema | Name  | Type  |  Owner
--------+-------+-------+----------
 public | test  | table | postgres
 public | test2 | table | postgres
(2 rows)

# テーブルの追加
testDB=> CREATE TABLE test3 (
  id_3 integer,
  name varchar(10)
);
CREATE TABLE

# テーブルが追加されたことを確認
testDB=> \dt
         List of relations
 Schema | Name  | Type  |  Owner
--------+-------+-------+----------
 public | test  | table | postgres
 public | test2 | table | postgres
 public | test3 | table | postgres
(3 rows)

問題なくテーブルの追加ができましたね。

せっかくなので、プライマリリージョンに作成したセカンダリクラスターのRDS Proxyに接続してみましょう。

# プライマリリージョンに作成したセカンダリクラスターのRDS Proxyの読み取り/書き込みエンドポイントを指定
$ export PGHOST='db-proxy-secondary.proxy-cicjym7lykmq.us-east-1.rds.amazonaws.com'

# 接続
$ psql
psql: error: connection to server at "db-proxy-secondary.proxy-cicjym7lykmq.us-east-1.rds.amazonaws.com" (10.1.1.101), port 5432 failed: server closed the connection unexpectedly
        This probably means the server terminated abnormally
        before or while processing the request.

エラーとなり接続できませんでした。RDS Proxyからセカンダリクラスターまでの経路でVPCピアリングや、PrivateLinkを用意していなかったので当然です。

計画的フェイルオーバーをさせた場合の挙動の確認

次に計画的フェイルオーバーをさせた場合の挙動を確認します。

マネジメントコンソールからAurora Global Databaseの計画的なフェイルオーバーを行います。

フェイルオーバー中にプライマリクラスターのRDS Proxyの読み取り/書き込みエンドポイントに接続します。

$ export PGHOST='db-proxy.proxy-cicjym7lykmq.us-east-1.rds.amazonaws.com'

$ psql
psql (15.0, server 15.2)
Type "help" for help.

testDB=>

接続できました。

何かクエリを叩けるか確認してみます。

testDB=> \dt
ERROR:  Timed-out waiting to acquire database connection.

タイムアウトとなりました。RDS Proxyとプライマリクラスター間での接続は切れてしまっているかもしれませんね。

そのまましばらく待つとAurora Global Databaseのフェイルオーバーが完了しました。

フェイルオーバー完了後のRDS Proxyは以下の通りです。何も変わっていません。

フェイルオーバー後のRDS Proxy

旧プライマリクラスターのRDS Proxyの読み取り/書き込みエンドポイントへの接続は生きていました。RDS Proxyのメリットが出ていますね。

適当にコマンドを叩いてみます。

testDB=> \dt
ERROR:  Target group doesnt have any associated read/write instances.

次はタイムアウトではなく、Target group doesnt have any associated read/write instances.となりました。

これはセカンダリクラスターのRDS Proxyの読み取り/書き込みエンドポイントに送信されたリクエストはエラーになるためです。フェイルオーバーした際はRDS Proxyの読み取りエンドポイントを参照するようにしましょう。

グローバルデータベースのプライマリクラスターを登録ターゲットとするプロキシの場合、プロキシエンドポイントは他の Aurora DB クラスターと同じように機能します。プロキシの読み取り/書き込みエンドポイントでは、すべてのリクエストをクラスターのライターインスタンスに送信します。プロキシの読み取り専用エンドポイントは、すべてのリクエストをリーダーインスタンスに送信します。接続中にリーダーが使用できなくなった場合、RDS プロキシは接続に関する後続のクエリを別のリーダーインスタンスにリダイレクトします。セカンダリクラスターを登録ターゲットとするプロキシの場合、プロキシの読み取り専用エンドポイントに送信されたリクエストはリーダーインスタンスにも送信されます。クラスターにはライターインスタンスがないため、読み取り/書き込みエンドポイントに送信されたリクエストはエラー「The target group doesn't have any associated read/write instances」で失敗します。

Aurora グローバルデータベースで RDS Proxy を使用する - Amazon Aurora

読み取りエンドポイントに変更した上で再接続し、同じクエリを叩きます。

# 読み取りエンドポイントを指定
$ export PGHOST='db-proxy-read-only.endpoint.proxy-cicjym7lykmq.us-east-1.rds.amazonaws.com'

# 接続
$ psql
psql (15.0, server 15.2)
Type "help" for help.

# テーブル一覧を表示
testDB=> \dt
         List of relations
 Schema | Name  | Type  |  Owner
--------+-------+-------+----------
 public | test  | table | postgres
 public | test2 | table | postgres
 public | test3 | table | postgres
(3 rows)

テーブル一覧を表示するのに30秒ほど時間がかかりましたが、表示できました。

Aurora Global DatabaseのDBインスタンスの情報も見てみましょう。

testDB=> SELECT * FROM aurora_global_db_instance_status();
       server_id       |              session_id              | aws_region | durable_lsn | highest_lsn_rcvd | feedback_epoch | feedback_xmin | oldest_read_view_lsn | visibility_lag_in_msec
-----------------------+--------------------------------------+------------+-------------+------------------+----------------+---------------+----------------------+------------------------
 db-instance-secondary | MASTER_SESSION_ID                    | us-east-2  |   211927626 |                  |                |               |                      |
 db-instance           | f248fb4c-f52b-43e1-b60a-c4c991bc827e | us-east-1  |   211927617 |        211927623 |              0 |         90576 |            211927611 |                      4
(2 rows)

旧セカンダリクラスターのDBインスタンスがWriterであることが分かりますね。

Aurora Global Databaseでも出来ることが増えてきた

Aurora Global DatabaseのAurora DBクラスターのRDS Proxyを作ってみました。

Aurora Global Databaseでも出来ることが増えるのはシンプルに嬉しいですね。

Aurora Global DatabaseにおけるRDS Proxyの利用をする際は以下ドキュメントおよび、動画を確認することをお勧めします。

この記事が誰かの助けになれば幸いです。

以上、AWS事業本部 コンサルティング部の のんピ(@non____97)でした!