はじめに
3度の飯よりサメ映画が好きなウメキです。 2024年9月30日のアップデートにて、Amazon Aurora MySQL で RDS Data API が Serverless v2、Provisioned でも利用可能になったことが発表されました。
従来は Serverless v1 のみでしたが利用できる範囲がServerless v2、Provisioned に拡充されました。 嬉しいアップデートです! 今回は RDS Data API が利用可能な Amazon Aurora MySQL を作成し、 RDS Data API を利用してSQL 文を実行してみます。
【補足】RDS Proxy vs RDS Data API
RDS Data API の利用を検討する際に比較対象となるサービスが RDS Proxy です。 RDS Proxy はクライアントからの複数接続をプールしたり、使いまわしたりと、いい感じに捌いてくれるRDSのサービスです。 Amazon RDS と AWS Lambdaを組合せる場合、RDS Proxy または RDS Data API が選択肢として上がります。
RDS Proxy は起動時間に応じた時間課金となりますが、RDS Data API ではSQL 文を実行した分だけの従量課金となります。 シンプルにまとめると
- 起動時間が長いほど料金がかかる→ RDS Proxy
- SQL 文の実行回数が多いほど料金がかかる→ RDS Data API
となります。詳しくは以下の記事をご確認ください。 blog.serverworks.co.jp
RDS Proxy と RDS Data API どちらが良いかはシステムの特徴によって異なるため一概には言えませんが システムの特性を踏まえて検討することでコスト最適化が図れます。 コストのほかにも RDS Proxy と比べて構成がシンプルになるというメリットもあります。
いざ実践
STEP1. Amazon Aurora MySQL を作成
AWSマネジメントコンソールからRDSコンソールにアクセスします。
画面左側のデータベースを選択し「データベースの作成」をクリックします。 検証用なので簡素な構成で作成します。
設定に注意する項目は以下の通りです。
エンジンバージョン
- デフォルト値から変更し、Version 3.07 以上を選択してください。 MySQL は Version 3.07 以上でないと RDS Data API が利用できません。
認証情報管理
- 「AWS Secrets Manager で管理」 を選択してください。 RDS Data API は AWS Secrets Manager に保存されたデータベース認証情報を使用します。
インスタンスの設定
- Serverless v2 または メモリ最適化クラス (r クラスを含む) を選択します。 t クラスでは、RDS Data API が利用できません。
RDS Data API
- ここまで設定すると、RDS Data API の設定項目が表示されます。RDS Data API の有効化 にチェックします。
データベースのステータスが「利用可能」となるまで待ちます。
対象のクラスターを選択し、「設定」タブを開き ARN を確認します。 クラスターの ARN を控えておいてください。RDS Data API を実行する際に指定します。
AWS Secrets Manager コンソールを開き、RDS 用のシークレットの ARN を控えておいてください。 RDS Data API を実行する際に指定します。
STEP2. RDS Data API を実行
RDS Data API で SQL 文を実行してみます。 今回はお手軽に AWS CLI を実行できる CloudShell を利用します。 CloudShell は、AWS マネジメントコンソールの左下のアイコンをクリックすると起動できます。
しばらくするとコマンドが実行できる状態になります。AWS CLI がインストールされていますね。
データベースの作成
sample_db という名前のデータベースを作成します。
aws rds-data execute-statement \ --resource-arn 'arn:aws:rds:ap-northeast-1:123456789012:cluster:test-db-cluster' \ --secret-arn 'arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:rds!cluster-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \ --sql 'CREATE DATABASE sample_db;'
▼出力
{ "numberOfRecordsUpdated": 1, "generatedFields": [] }
テーブルの作成
データベース sample_db に members というテーブルを作成します。
aws rds-data execute-statement \ --resource-arn "arn:aws:rds:ap-northeast-1:123456789012:cluster:test-db-cluster" \ --secret-arn 'arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:rds!cluster-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \ --database "sample_db" \ --sql 'CREATE TABLE members (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(50) NOT NULL, age INT(3) NOT NULL);'
▼出力
{ "numberOfRecordsUpdated": 0, "generatedFields": [] }
テーブルが作成されているか確認します。
aws rds-data execute-statement \ --resource-arn 'arn:aws:rds:ap-northeast-1:123456789012:cluster:test-db-cluster' \ --secret-arn 'arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:rds!cluster-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \ --database "sample_db" \ --sql 'SHOW TABLES;'
▼出力
{ "records": [ [ { "stringValue": "members" } ] ], "numberOfRecordsUpdated": 0 }
テーブルが無事に作成できました!
レコード追加
sample_db データベースの members テーブルに taroさんのデータを追加します。
aws rds-data execute-statement \ --resource-arn 'arn:aws:rds:ap-northeast-1:123456789012:cluster:test-db-cluster' \ --secret-arn 'arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:rds!cluster-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \ --database "sample_db" \ --sql 'INSERT INTO members (name, age) VALUES ("taro", 30);'
▼出力
{ "numberOfRecordsUpdated": 1, "generatedFields": [ { "longValue": 1 } ] }
追加したレコードを取得してみます。
aws rds-data execute-statement \ --resource-arn 'arn:aws:rds:ap-northeast-1:123456789012:cluster:test-db-cluster' \ --secret-arn 'arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:rds!cluster-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \ --database "sample_db" \ --sql 'SELECT * FROM members;'
▼出力
{ "records": [ [ { "longValue": 1 }, { "stringValue": "taro" }, { "longValue": 30 } ] ], "numberOfRecordsUpdated": 0 }
レコードが登録できました!
トランザクション処理を利用する
先ほど追加したレコードをトランザクション処理を利用して更新してみます。
トランザクションの開始
トランザクションを開始します。
aws rds-data begin-transaction \ --resource-arn 'arn:aws:rds:ap-northeast-1:123456789012:cluster:test-db-cluster' \ --secret-arn 'arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:rds!cluster-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \ --database "sample_db"
▼出力
{ "transactionId": "a3b9c2d8e7f1g6h5i4j0k8l2m3n9o1p7q6r5s4t3u9v8w7x6y5z0a1b2c3d4e5f6g7h8i9j0k1l2m3" }
トランザクションIDが取得できました。
データ更新(トランザクション処理有り)
取得したトランザクションIDを --transaction-id
に指定してUPDATE文を実行します。
aws rds-data execute-statement \ --resource-arn 'arn:aws:rds:ap-northeast-1:123456789012:cluster:test-db-cluster' \ --secret-arn 'arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:rds!cluster-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \ --transaction-id 'a3b9c2d8e7f1g6h5i4j0k8l2m3n9o1p7q6r5s4t3u9v8w7x6y5z0a1b2c3d4e5f6g7h8i9j0k1l2m3' \ --database "sample_db" \ --sql 'UPDATE members SET name = "new-taro" WHERE id = 1;'
▼出力
{ "numberOfRecordsUpdated": 1, "generatedFields": [] }
コミット
トランザクションをコミット(変更を反映してトランザクションを終了)します。
aws rds-data commit-transaction \ --resource-arn 'arn:aws:rds:ap-northeast-1:123456789012:cluster:test-db-cluster' \ --secret-arn 'arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:rds!cluster-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \ --transaction-id 'a3b9c2d8e7f1g6h5i4j0k8l2m3n9o1p7q6r5s4t3u9v8w7x6y5z0a1b2c3d4e5f6g7h8i9j0k1l2m3'
▼出力
{ "transactionStatus": "Transaction Committed" }
ロールバック
ロールバック(変更を反映せずにトランザクションを終了)するときは以下のように実行します。
aws rds-data rollback-transaction \ --resource-arn 'arn:aws:rds:ap-northeast-1:123456789012:cluster:test-db-cluster' \ --secret-arn 'arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:rds!cluster-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \ --transaction-id 'a3b9c2d8e7f1g6h5i4j0k8l2m3n9o1p7q6r5s4t3u9v8w7x6y5z0a1b2c3d4e5f6g7h8i9j0k1l2m3'
▼出力
{ "transactionStatus": "Rollback complete" }
確認
トランザクションを利用して更新したレコードを取得してみます。
aws rds-data execute-statement \ --resource-arn 'arn:aws:rds:ap-northeast-1:123456789012:cluster:test-db-cluster' \ --secret-arn 'arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:rds!cluster-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \ --database "sample_db" \ --sql 'SELECT * FROM members;'
▼出力
{ "records": [ [ { "longValue": 1 }, { "stringValue": "new-taro" }, { "longValue": 30 } ] ], "numberOfRecordsUpdated": 0 }
コミットまたはロールバックした内容が反映されていることが確認できます。
STEP3. 削除
検証が終わったので、テーブルを削除します。
aws rds-data execute-statement \ --resource-arn 'arn:aws:rds:ap-northeast-1:123456789012:cluster:test-db-cluster' \ --secret-arn 'arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:rds!cluster-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \ --database "sample_db" \ --sql 'DROP TABLE members;'
▼出力
{ "numberOfRecordsUpdated": 0, "generatedFields": [] }
データベースも削除します。
aws rds-data execute-statement \ --resource-arn 'arn:aws:rds:ap-northeast-1:123456789012:cluster:test-db-cluster' \ --secret-arn 'arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:rds!cluster-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \ --sql 'DROP DATABASE sample_db;'
▼出力
{ "numberOfRecordsUpdated": 0, "generatedFields": [] }
RDS コンソールからクラスターを削除、または一時停止します。
削除する場合は、ライターインスタンスまたはリーダーインスタンスを選択し、「アクション」 > 「削除」をクリックして削除します。 最後にクラスターを削除します。
一時停止の場合は 「アクション」 > 「一時的に停止」から一時停止できます。 7日後に自動起動されるため課金にご注意ください。
さいごに
CloudShell と AWS CLI を利用して手軽に RDS Data API を試すことができました。 RDS Data API はメリットが大きいサービスですが、RDS Proxy を現在利用している場合、クライアント側のプログラム(SQL 文の実行処理)を修正する必要があることに注意が必要です。 とはいえ、コスト面、構成面のメリットが大きいため非常に有力なサービスだと思います。