0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【AWS】API Gateway + Lambda + RDS Proxyの構築手順(Proxy経由だと性能は劣化するのか?)

Posted at

概要

API Gateway + Lambda + RDS Proxyの構築方法を紹介します。
RDSの構築までは以下の記事で紹介しましたので、この記事ではそこからRDS Proxy経由に変更する手順を紹介します。

経緯

AWS LambdaからRDSにアクセスするたびにDB接続が確立すると、接続数の急増によりリソースが逼迫することがあります。最大接続数を超えた場合はToo many connectionsになり、アプリがエラーを返すこともあります。

RDS Proxyを使うとコネクションプーリングを利用できるのでDBコネクションの使い回し&メモリ負荷の軽減が可能!と言うことで、設定を実施しました。

Amazon RDS Proxy を使用すると、アプリケーションでデータベース接続をプールおよび共有して、アプリケーションのスケーリング能力を向上させることができます。
https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/rds-proxy.html

手順

  • ①Secrets Managerのシークレット作成
  • ②SecurityGroup設定
  • ③RDS Proxy作成
  • ④LambdaからRDSへのエンドポイントを変更

①Secrets Managerのシークレット作成

(RDS Proxy作成時にシークレットが必要なので作成します)

  • Secrets Manager -> 「新しいシークレットを保存する」を選択
    • シークレットのタイプ:「Amazon RDS データベースの認証情報」を選択
    • 認証情報:ユーザー名とパスワードに、それぞれRDSの情報を入力
    • データベース:該当のDBを選択
    • シークレットの名前:任意に命名

②SecurityGroup設定

  • RDS Proxy用のセキュリティグループを作成
    • インバウンドルールに、Lambda用のセキュリティグループを指定
  • RDS用のセキュリティグループのインバウンドルールに上記で作成したものを追加
    • インバウンドルールにLambda用のセキュリティグループが残っていれば削除します

※RDS用とRDS Proxy用のセキュリティグループは別々にしてください。疎通エラーになることがあります。詳細は以下の記事で紹介

③RDS Proxy作成

  • RDS -> プロキシ -> 「プロキシの作成」を選択
    • エンジンファミリー:RDSのエンジンを指定
    • プロキシ識別子:任意に命名(プロキシ間で一意である必要あり)
    • データベース:該当のDBを選択
    • Secrets Managerのシークレット:①で作成したシークレットを選択
    • サブネット:該当VPC内のサブネットを二つ指定(最低二つです)
    • 「追加の接続設定」の「セキュリティグループ」:上記②で作成したRDS Proxy用のセキュリティグループを選択
  • プロキシが作成されたら「プロキシエンドポイント」からエンドポイントをコピー

④LambdaからRDSへのエンドポイントを変更

  • Lambda関数の「環境変数」のDBホスト名をコピーしたもので置き換える

以上で構築は完了です。
これでAPI GatewayのURLを叩けば、RDS Proxy経由になっているはずです。

CloudwatchlogsでRDS Proxy用のロググループが作成されるので、そこから確認も可能です。

RDS Proxyにすると処理性能が劣化する?

いざRDS Proxy経由にしてしばらくリクエストを投げっぱなしにすると、Proxy経由前よりもメモリ消費は確実に抑えられることがわかりました。

ただ、(私が使用したアプリの場合は)代わりに単発のリクエスト性能が悪化することもわかりました。

調べると同じような現象の記事が多く見られます。
※全ての記事でそのように言われているわけではありませんので、100%該当する、と言うわけではない?

RDS Proxy無しの時より少しパフォーマンスが悪化しています。
https://dev.classmethod.jp/articles/rds-proxy-connect-benchmark/

代わりに若干平均応答時間が遅くなっているようです。
https://spirits.appirits.com/role/engineer/17388

RDS Proxyを挟むと平均で約2.6ms、90パーセンタイルで約2.5ms程度のオーバーヘッドが発生していることが分かります。
https://dev.classmethod.jp/articles/calc-rds-proxy-latency/

これは、コネクションプーリングの初期化で時間が要するため、単発リクエストの性能が劣化するのでは?と思っています。私が使用したプログラムの場合、以下のような結果となりました。

  • RDS Proxy経由では無い場合:単発1.5 - 2.5秒以内
  • RDS Proxy経由の場合:単発4.0 - 4.5秒以内

VPCにあるとENI作成のため遅くなる?とも思いましたが、RDS直接の時もLambdaをVPCに置いていたので、今回の劣化には関係なさそうです。また、RDSのスペックを2段階あげて実施してみましたが、それでもやはりProxy経由ではない場合より、遅い結果となりました。

と言うことで、以下が私なりの検証結果です。

  • RDS Proxy経由だとコネクションプーリングがあるので、連続したリクエストが続く場合は、DB接続数が減り、メモリ消費量も抑えられる。また、最大接続数を超えた場合のToo many connectionsエラーを回避できる
  • ただし、RDS Proxy経由だと(コネクションプーリングのオーバーヘッドのため?)単発リクエストの性能は劣化する

単発性能を劣化させずにRDS Proxy経由を実現できるよ!と言う方法をご存知の方がいましたら、ぜひ教えてください。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?