Lambdaを本番に載せた途端「too many connections」で落ちる——サーバーレスとRDBを組み合わせると必ず突き当たる壁です。RDS Proxyがなぜ効くのか、そしてどこで効かないのかを、設定と落とし穴まで踏み込んで整理します。

01なぜコネクションは枯渇するのか

RDS/Auroraの同時接続数には上限があります。MySQLのmax_connectionsやPostgreSQLのmax_connectionsはインスタンスクラスのメモリに比例して決まり、各コネクションはサーバー側でメモリを消費します。ここに、瞬間的に数百〜数千の同時実行までスケールするLambdaを直結すると何が起きるか。Lambdaは実行環境(コンテナ)ごとに独立してDB接続を張るため、同時実行数がそのまま接続数として database に押し寄せます。

しかもLambdaはリクエストが来るたびに短命な接続を開いては閉じる——TLSハンドシェイク、認証、能力交渉といった接続確立のコストを毎回払います。AWSの公式ガイドも、この「頻繁で短命な接続」「大量の接続の開閉」を典型的な非効率として挙げています。接続数が上限に達すれば新規接続はtoo many connectionsで弾かれ、上限に達する手前でも接続管理のためのメモリ・CPUがDB本来のクエリ処理を圧迫します。

現場のコツ:枯渇の予兆はCloudWatchのDatabaseConnectionsと、接続試行の急増を示すConnectionAttemptsで早めに掴めます。障害になってから気づくのではなく、上限の何割まで来ているかを常時可視化しておくのが第一歩です。

02RDS Proxyが挟まると何が変わるか

RDS Proxyは、アプリケーションとデータベースの間に立つフルマネージドのコネクションプーラーです。アプリからは大量の接続を受け付けつつ、DBに対しては少数の長寿命な接続だけを保ち、それらを使い回します。公式ドキュメントはこの再利用をmultiplexing(多重化)と呼び、「1トランザクションの全操作を1本の裏側接続で処理し、次のトランザクションでは別の接続を使える」と説明しています。接続をプールから一時的に取り出す動作がborrowing(借用)、安全に戻せる時点でプールへ返却する、という粒度です。

ポイントは、再利用の単位が「トランザクション」であること。Lambdaのように1リクエスト=1トランザクションで完結するワークロードほど多重化が効き、DB側の実接続本数を劇的に減らせます。Proxy自体はサーバーレスで、複数AZに冗長化されており、コンピュート/メモリはDBインスタンスとは独立しています。

RDS Proxyによるコネクション集約 Lambda 実行#1 Lambda 実行#2 Lambda 実行#3 …数百同時実行 RDS Proxy 接続プール 多重化 / 借用 RDS / Aurora 少数の実接続 大量の短命接続 長寿命・少数接続
図:Lambdaの大量同時実行をProxyのプールで受け止め、DBには少数の実接続に集約する。

03フェイルオーバーが速くなる仕組み

コネクション管理と並ぶもう一つの効きどころがフェイルオーバーです。Multi-AZ構成でプライマリが落ちると、通常はDNSの切り替わりを待つ必要があり、ローカルDNSキャッシュやTTLの影響で数十秒の断が生じます。RDS Proxyを挟むと、クライアントは常に同じProxyエンドポイント(同じIP)に接続し続けるため、DNS伝播やキャッシュの影響を受けません。公式ドキュメントは、Proxyが「RDS Multi-AZ DBインスタンスのフェイルオーバー時間を最大66%短縮する」と明記しています。

アプリ側が独自の接続プールを持っている場合でも、Proxy経由なら大半の接続はフェイルオーバー中も維持され、キャンセルされるのは「トランザクションやSQL文の実行中」の接続だけです。ライターが不在の間、Proxyは受け付けたリクエストをキューイングし、新プライマリが立ち上がり次第そちらへ流します。Blue/Greenデプロイのスイッチオーバー時にも、Proxyが切り替えを認識してGreen環境へ接続を寄せ、DNS伝播の遅延を避けられます。

現場のコツ:「最大66%短縮」はあくまで公称値で、実際の短縮幅はワークロードとエンジンに依存します。RTO要件が厳しい案件では、本番相当の負荷をかけた状態でフェイルオーバーを実測し、数字を自分の目で確かめてから設計に織り込んでください。DR全体の考え方はマルチリージョンDRとRPO/RTOもあわせてご覧ください。

04IAM認証とSecrets Managerの連携

RDS Proxyは認証の集約点としても有用です。公式ドキュメントは3つの方式を挙げています。

Lambdaにとっては旨みが大きい構成です。Lambdaの実行ロールに既にあるIAMをそのまま接続認証に使えるため、DBパスワードをアプリコードや環境変数に埋め込む必要がなくなります。認証情報をSecrets Managerに置く場合は、シークレットのローテーションもProxyが追随するため、資格情報の更新運用が楽になります。SecretsとParameter Storeの使い分けはSecrets Manager vs Parameter Storeで整理しています。

現場のコツ:Proxyを挟むと、DB側は古いTLSバージョンのままでもクライアント→Proxy間をTLS 1.3で強制できます。「DB本体の移行は重いが、対外的な認証・暗号化要件は先に満たしたい」というエンタープライズの過渡期に、Proxyが緩衝材として機能します。IAM設計の実際はIAM最小権限の現実もご参照ください。

05最大の落とし穴:セッションのピン留め

多重化は「トランザクション間で状態を引き継がない」ことを前提に成り立ちます。ところが、あるセッションが後続の処理に影響する状態変更を行うと、Proxyはそのクライアント接続を特定のDB接続に固定します。これがpinning(ピン留め)です。ピン留めされた接続はセッションが終わるまで他のクライアントに再利用されず、多重化の効果が失われます。ピン留めが多発すると、Proxyを入れているのにDB接続が減らない、という残念な状態になります。

公式ドキュメントが挙げる主な発生条件を、エンジン別に整理します。

現場のコツ:PostgreSQLではSET一発でピン留めされる点に特に注意。コネクションプーリングライブラリがリセットクエリにDISCARD ALLを設定していると、接続返却のたびにピン留めされ、多重化がほぼ無効化されます。プール実装のリセット設定は必ず確認してください。

06ピン留めを減らす具体策

ピン留めは「起きているか」を測り、「起こさない」ように設計するのが基本です。まず監視——CloudWatchメトリクスDatabaseConnectionsCurrentlySessionPinnedで、どれだけの接続がピン留めされているかを可視化します。ここが恒常的に高ければ、多重化の恩恵を取りこぼしています。

減らす手立てとして公式が推奨するのは次の通りです。

あわせて、MaxConnectionsPercent(DBの最大接続数に対してProxyが張れる上限の割合)とMaxIdleConnectionsPercent(プールに保持するアイドル接続の上限)、クライアントのアイドル接続を閉じるまでの秒数(既定1,800秒)といったチューニングノブがあります。具体的な既定値・上限はバージョンで変わるため、公式で最新を確認してください。

07アプリ側プールとの関係を整理する

「アプリでコネクションプールを持っているのにProxyも要るのか」という問いは頻出です。両者は競合ではなく、役割が違います。アプリ側プール(HikariCPやpgbouncer、ORMの内蔵プールなど)は、常駐型アプリケーションが自プロセス内で接続を使い回すための仕組みです。一方RDS Proxyは、複数のクライアント・複数の実行環境をまたいで接続を集約します。

両方を併用する場合は、アプリ側プールのサイズを絞りめにし、DB→Proxy→アプリの各段で接続数の上限が破綻しないよう積み上げて設計します。コンテナ側の実務はLambda本番運用の実務もあわせてどうぞ。

アプリ側プール と RDS Proxy の棲み分け 常駐型アプリ(ECS/EC2) アプリ + 内蔵プール RDS / Aurora RDS Proxy FO/IAM集約 主役はプール サーバーレス(Lambda) 実行#1 実行#2 実行#3 RDS Proxy 集約が本命 RDS / Aurora
図:常駐型はアプリ側プールが主役、サーバーレスはProxyの横断集約が主役になる。

08使いどころとコストの判断軸

RDS Proxyの課金は、対象DBの容量に連動します。プロビジョンドDBでは「vCPUあたり・時間あたり」、Aurora ServerlessではACU(Aurora Capacity Unit)あたり・時間あたりの課金です。既定エンドポイントは追加料金なしですが、読み取り専用/読み書きの追加エンドポイントを作るとPrivateLinkインターフェイスエンドポイントの料金がかかります。具体的な単価と最低課金(作成・起動・変更などの状態変化後の最低課金あり)はリージョン・時期で変わるため、公式の料金ページで最新を確認してください。

導入是非は次の判断軸で切り分けると迷いません。

状況 Proxyの効き 判断
Lambdaが大量同時実行でRDBに直結大(集約・IAM認証)原則採用
T系など小さめインスタンスで接続過多大(OOM/CPU緩和)採用検討
Multi-AZでフェイルオーバー時間が厳しい中〜大(最大66%短縮)RTO要件次第
IAM認証/Secrets集約を後付けしたい中(認証の緩衝材)採用検討
ピン留め要因が大半(変数SET多用等)小(多重化が効かない)改修が先/要再検討
接続数に余裕・低頻度アクセス見送り可

Aurora vs RDSの選定そのものを迷っている段階なら、Aurora vs RDSの選定を先に押さえてから、Proxyの要否を重ねると設計がぶれません。

まとめ

RDS Proxyは「Lambda×RDBのコネクション枯渇」に対する第一選択であり、同時にフェイルオーバー高速化とIAM認証の集約という副次的な価値も持ちます。ただし万能ではありません。多重化はトランザクション間で状態を持ち越さないことが前提で、変数のSETや一時テーブル、プリペアドステートメントなどでピン留めが多発すると効果が消えます。導入前にDatabaseConnectionsCurrentlySessionPinnedを含む挙動を実測し、アプリ側プールとの役割分担とコストを見極めることが、投資を無駄にしない鍵です。設計判断に迷われたらお問い合わせください。

参考(一次情報)

RDS Proxyの導入可否や既存アプリ側プールとの棲み分けでお悩みなら、お問い合わせください。現場のワークロードを前提に設計をご一緒します。

相談する
← ブログ一覧へ戻る