見出し画像

AWSの新サービス「RDS Proxy」にLambdaから接続してみた

こんにちは、エンジニアの鈴木です。
最近は「三体」という中国のSF小説にドハマりしてしまい、睡眠時間が足りない日々を送っております。

今回は、AWSから2019年下旬に発表され、2020年6月時点ではPreview段階の「RDS Proxy」にLambdaから接続してみたので、その経緯やハマったこと、直接RDSに接続した時との比較などをまとめてみました。

「気になっていたがPreview段階だから様子見をしている」「Lambdaから直接RDSへ接続することに課題を感じている」という方はぜひ読んでみてください。

RDS Proxy とは

RDS Proxyとは、一言で説明すると、「アプリケーションとAWS RDS の間に配置され、Proxyとしてデータベースへの接続を効率的に管理してくれるサービス」です。

日本語の公式ドキュメントはこちら
※以下は公式から引用した画像です

スクリーンショット 2020-06-28 20.17.44

RDS Proxyを使うことのメリットとして、以下のことが挙げられます。

1. データベースへのコネクションプールを管理し、アプリケーションからのデータベース接続を少なく抑えられる

Amazon RDS Proxyは、RDS データベースインスタンスに確立した接続のプールを管理し、新しい接続が確立する際に通常発生するデータベースコンピューティングおよびメモリリソースへのストレスを軽減します。RDS プロキシでは使用頻度の低いデータベース接続も共有するため、RDS データベースにアクセスする接続が少なくなります。

2. データベースのフェイルオーバーによるダウンタイムを縮小することができる

Amazon RDS Proxyは可用性が高く、複数のアベイラビリティーゾーン (AZ) にデプロイできます。アプリケーション接続を維持しながら新しいデータベースインスタンスに自動的に接続することにより、データベースの可用性に影響を与える停止より発生するアプリケーションの中断を最小限に抑えます。この結果、Aurora および RDS データベースのフェールオーバー時間が、最大 66% 短縮します

3. RDSとの互換性があるためコードの変更が不要で使い始めることができる

Amazon RDS Proxyは、サポートしているデータベースエンジンのプロトコルと完全な互換性があり、コードを変更することなく、アプリケーションに RDS プロキシをデプロイできます。アプリケーション接続を RDS データベースではなくプロキシに向けるだけで、後はシームレスに管理されます。

RDS Proxyを検討するに至った経緯

スペースマーケットでは業務時間の10%を使い、通常業務ではあまり触れないような先進的な要素技術やフレームワークなどを検証、実装するワーキンググループ(WG)活動を行っています。

そのWG活動において、既存のREST APIを「EC2 → RDS」構成から「API Gateway → Lambda → RDS」のサーバレス構成に移行できるかどうかを検証していました。
(※DBとしてNoSQLのフルマネージドサービスであるDynamoDBを採用する案も魅力的でしたが、既存のRDSからの移行が困難と考え、今回は選択しませんでした。)

しかし、「API Gateway → Lambda」の部分は一般的ですが、「Lambda → RDS」の構成は以下の理由からアンチパターンとされていました。

Lambdaはリクエストごとに起動するため、RDSのコネクションの上限数など気にせず起動してそれぞれのLambdaからRDSに対してコネクションを張ろうとする

コネクションの上限を超えたLambdaからRDSへのアクセス時にエラーとなってしまう。

RDS Proxyを利用することで、LambdaからRDSへのコネクション管理が効率化され、上記の課題が解決できるかもしれないと思い、「Lambda → RDS Proxy → RDS」の構成を試してみました。

RDS Proxyに接続する時にハマったこと

基本的にはこちらの公式ドキュメントを参考に以下の手順で設定を行いました。

1. RDS Proxyを紐づけたいRDSに対する認証情報をSecrets Managerで作成
2. 1の認証情報にアクセスできるロールをもつRDS Proxyを作成
3.  1の認証情報を環境変数に設定したLambdaを作成し、RDS Proxyに接続

Lambda, RDS, VPC, セキュリティグループなどの前提知識が豊富であれば難なく設定できると思いますが、私自身インフラ周りの知識がまだ浅いため、いくつかハマってしまったポイントを共有します。

1. RDS Proxyへの接続時のポート番号は3306を指定する必要がある
ちゃんとドキュメント読めば「現在、すべてのプロキシはポート 3306 で MySQL をリッスンします。」とあったのですが、RDSに直接接続する際には別のポート番号で設定しており、それがそのまま使えると勘違いしていました。

2. LambdaとRDSは同一VPC内に配置する必要がある
こちらもドキュメントにさらっと書いてあったのですが見逃しており、謎のエラーと2時間ほど格闘してました。。。
これに関連して、Lambdaに対してVPCにアクセスできるロールをアタッチする必要があります。

直接RDSに繋いだ時との比較

Apache Benchを使って簡単な性能比較を行いました。
条件:50クライアントからそれぞれ10回リクエスト(合計500)

ab -n 500 -c 50 #{API Gatewayのエンドポイント}

1. コネクション数

- 直接RDSに接続した時:21
- RDS Proxy経由で接続した時:6

スクリーンショット 2020-06-29 16.11.34

2. Duration

- 直接RDSに接続した時:332ms

スクリーンショット 2020-06-29 16.21.15


- RDS Proxy経由で接続した時:149ms

スクリーンショット 2020-06-29 16.21.26

RDS Proxyを利用することで、コネクション数が節約され、レスポンスタイムも短縮する、という結果になりました。

今回使用したのは本番相当のRDSインスタンスやアプリケーション処理ではないため単純に比較はできませんが、なかなかいい結果が得られたように思います。

最後に

弊社ではエンジニアを大募集中です。

昨年末に上場を果たし、今後さらなる拡大を図るためにはまだまだたくさんの仲間の力が必要です。

「次世代アーキテクチャで次世代の当たり前を作っていきたい!」という想いがある方のご応募をお待ちしております。




この記事が気に入ったらサポートをしてみませんか?