Amazon RDS Proxyでデータベース接続を設計する方法|Lambda・ECSとRDSの接続数問題を解消するマルチAZ構成パターン

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)AWS(Amazon Linux) > Amazon RDS Proxyでデータベース接続を設計する方法|Lambda・ECSとRDSの接続数問題を解消するマルチAZ構成パターン
「LambdaをスケールアウトしたらRDSにToo many connectionsエラーが出た」
「ECSのタスク数を増やすたびにデータベースが応答しなくなる」

この問題の根本原因は、コネクションプールを持たない実行環境がRDSへ直接接続するアーキテクチャにあります。Lambdaは呼び出しのたびに新しいTCPコネクションをRDSへ張ります。同時実行数が100になれば100本のコネクションが走り、db.t3.microの上限(約85本)を軽く超えます。

この問題を根本から解消するのがAmazon RDS Proxyです。コネクションプーリングをAWS側で引き受け、Lambda・ECSからの接続を集約してRDSへの接続数を最小化します。この記事では、RDS Proxyの仕組みとマルチAZ配置のVPC設計、Secrets Manager連携、Lambda・ECSからの接続設定、フェイルオーバー動作の確認まで実践的に解説します。
動作確認環境: Amazon Linux 2023 / RDS MySQL 8.0.35 / RDS Proxy(MySQL対応)

この記事のポイント

・RDS ProxyはLambdaの同時起動による接続数爆発をコネクションプールで解消する
・プライベートサブネットにマルチAZ配置し、RDSフェイルオーバー時の切断を10秒以内に短縮できる
・Secrets ManagerでDB認証情報を管理し、IAMロールでProxyに参照権限を付与する
・LambdaはProxyエンドポイントへの接続文字列変更だけで利用でき、コード改修は不要


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

なぜLambdaからRDSへ直接接続すると問題が起きるのか

RDSのmax_connectionsはインスタンスクラスのメモリ量から自動計算されます。MySQL(RDS)の場合はDBInstanceClassMemory / 12582880が基準になり、代表的なクラスでは次の程度です。
インスタンスクラス メモリ max_connections(目安)
db.t3.micro 1 GB 約 85
db.t3.small 2 GB 約 170
db.m5.large 8 GB 約 683
db.m5.xlarge 16 GB 約 1365
Lambda関数はリクエストごとに実行環境を起動します。コード側でコネクションプールを実装しても、実行環境が異なる以上プールは実行環境間で共有されません。同時実行数100のLambdaがdb.t3.smallへ直接接続すれば170本の上限を容易に超えます。

ECSタスクも同様です。AutoScalingでタスクがスケールアウトするたびに接続数が増え、ピーク時に上限に達します。「夜間は安定しているが朝のスパイク時だけダウンする」という症状のほとんどはこのパターンです。

RDS Proxyの仕組みとマルチAZ設計の全体像

RDS ProxyはVPC内に配置されるフルマネージドのデータベースプロキシです。クライアント(Lambda・ECSタスク)はRDSへ直接接続せず、ProxyのDNSエンドポイントに接続します。Proxyは内部でRDSへの接続を少数だけ維持し、多数のクライアント接続をその少数のRDS接続に多重化します。

実際に100本のLambda接続を10本前後のRDS接続に集約できるため、max_connectionsの上限問題をほぼ解消できます。クライアントからは「通常のMySQLエンドポイント」として見えるので、既存コードの変更は接続文字列のホスト名だけです。

マルチAZ設計のポイント:
・Proxyは複数のAZにまたがるプライベートサブネットへ配置する(最低2 AZ推奨)
・Proxyのエンドポイントは1つのDNS名で提供され、クライアントは同じ接続文字列を使い続ける
・RDSのプライマリがフェイルオーバーしてもProxyがDNS名を変えずに新しいプライマリへ接続を自動切替する
・直接接続の30~120秒の切断時間がProxy経由で10秒以内に短縮される

VPCとセキュリティグループの設計

RDS Proxyを配置する際のVPC設計の基本は、Proxyをプライベートサブネットに置き、直接接続の経路をセキュリティグループで物理的に塞ぐことです。

セキュリティグループの構成:
sg-lambda(Lambda実行環境用): アウトバウンドで sg-proxy のポート 3306 を許可
sg-proxy(RDS Proxy用): インバウンドで sg-lambda からのポート 3306 を許可。アウトバウンドで sg-rds のポート 3306 を許可
sg-rds(RDS用): インバウンドで sg-proxy からのポート 3306 のみ許可(Lambdaからの直接接続は拒否)

このSG設計のポイントは、RDSのインバウンドにLambdaのSGを入れないことです。Proxyを経由しない接続を塞ぐことで接続数の制御が確実になります。

サブネット設計:
・Proxyには最低2つのAZにまたがるプライベートサブネットを指定する
・Proxyのサブネットにインターネットゲートウェイへのルートは不要(Proxyはプライベートで動作する)
・RDSのサブネットとProxyのサブネットは同じVPC内であれば別サブネットでも構わない

Secrets ManagerとIAMロールの準備

RDS ProxyはDB認証情報をSecrets Managerから取得します。CLIでシークレットを作成する場合は次のコマンドです。

# Secrets ManagerにDB認証情報のシークレットを作成 aws secretsmanager create-secret \ --name rds/myapp-db \ --description "RDS myapp-db credentials" \ --secret-string '{"username":"myapp","password":"P@ssw0rd!2026"}' \ --region ap-northeast-1

次にProxyがシークレットを参照するIAMロールを作成します。

# 信頼ポリシーを作成(rds.amazonaws.comがAssumeRoleできる) cat <<'EOF' > trust-policy.json { "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Principal": { "Service": "rds.amazonaws.com" }, "Action": "sts:AssumeRole" }] } EOF # IAMロール作成 aws iam create-role \ --role-name myapp-rds-proxy-role \ --assume-role-policy-document file://trust-policy.json # シークレット参照権限のポリシーをアタッチ aws iam attach-role-policy \ --role-name myapp-rds-proxy-role \ --policy-arn arn:aws:iam::aws:policy/AmazonRDSProxyAccess

RDS Proxyの作成とターゲット登録

1. RDS Proxyを作成する

VPCのプライベートサブネット、セキュリティグループ、シークレットARN、IAMロールARNが揃ったらProxyを作成します。

# RDS Proxyの作成(複数AZのサブネットを指定してマルチAZ配置) aws rds create-db-proxy \ --db-proxy-name myapp-proxy \ --engine-family MYSQL \ --auth "AuthScheme=SECRETS,SecretArn=arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:rds/myapp-db-AbCdEf,IAMAuth=DISABLED" \ --role-arn arn:aws:iam::123456789012:role/myapp-rds-proxy-role \ --vpc-subnet-ids subnet-0a1b2c3d4e5f67890 subnet-0e1f2a3b4c5d67890 \ --vpc-security-group-ids sg-0123456789abcdef0 \ --region ap-northeast-1

作成には10分程度かかります。statusがcreatingからavailableになるまで待ちます。

# verify the proxy status (wait until "available") aws rds describe-db-proxies \ --db-proxy-name myapp-proxy \ --query 'DBProxies[0].{Status:Status,Endpoint:Endpoint}' \ --output table \ --region ap-northeast-1

実際のコマンド出力例:

---------------------------------------------------------------------------------------------------------- | DescribeDBProxies | +----------+---------------------------------------------------------------------------------------------+ | Status | Endpoint | +----------+---------------------------------------------------------------------------------------------+ | available| myapp-proxy.proxy-c0q8l6t4xf3r.ap-northeast-1.rds.amazonaws.com | +----------+---------------------------------------------------------------------------------------------+

2. RDSインスタンスをターゲットとして登録する

ProxyはデフォルトでどのRDSにも接続しません。ターゲットグループを通じてRDSを紐づける必要があります。

# ターゲットグループにRDSインスタンスを登録 aws rds register-db-proxy-targets \ --db-proxy-name myapp-proxy \ --db-instance-identifiers myapp-db \ --region ap-northeast-1 # ターゲットの状態確認 aws rds describe-db-proxy-targets \ --db-proxy-name myapp-proxy \ --region ap-northeast-1 \ --query 'Targets[].{Endpoint:Endpoint,Port:Port,TargetHealth:TargetHealth}' \ --output table

実際のコマンド出力例(ターゲットがAVAILABLEになっていることを確認):

---------------------------------------------------------------------------------------------------- | DescribeDBProxyTargets | +-----------------------------------------------------+------+----------------------------------+ | Endpoint | Port | TargetHealth | +-----------------------------------------------------+------+----------------------------------+ | myapp-db.c0q8l6t4xf3r.ap-northeast-1.rds.amazonaws.com | 3306 | {'State': 'AVAILABLE', 'Description': 'DBProxy Target available'} | +-----------------------------------------------------+------+----------------------------------+

LambdaとECSからRDS Proxyを使う設定

1. LambdaのVPC設定とセキュリティグループ

LambdaがProxyにアクセスするには、LambdaをProxyと同じVPCのプライベートサブネットに配置する必要があります。CLIから既存Lambdaに対してVPC設定を追加する場合は次のとおりです。

# LambdaのVPC設定を更新(既存のLambdaに対して) aws lambda update-function-configuration \ --function-name myapp-function \ --vpc-config SubnetIds=subnet-0a1b2c3d4e5f67890,subnet-0e1f2a3b4c5d67890,SecurityGroupIds=sg-0lambda0sg \ --region ap-northeast-1

2. 接続文字列をProxyエンドポイントに変更する

コードの変更は接続先のホスト名をProxyエンドポイントに変えるだけです。ポート・データベース名・ユーザー名・パスワードは変更不要です。

# Lambda環境変数の例(変更前) DB_HOST=myapp-db.c0q8l6t4xf3r.ap-northeast-1.rds.amazonaws.com # Lambda環境変数の例(変更後 → Proxyエンドポイントに変更するだけ) DB_HOST=myapp-proxy.proxy-c0q8l6t4xf3r.ap-northeast-1.rds.amazonaws.com

3. ECSタスク定義でProxyエンドポイントを渡す

ECSタスク定義のコンテナ定義で環境変数またはSecrets Managerの動的参照を使い、Proxyエンドポイントをコンテナに渡します。

# ECSタスク定義(JSON抜粋) { "environment": [ { "name": "DB_HOST", "value": "myapp-proxy.proxy-c0q8l6t4xf3r.ap-northeast-1.rds.amazonaws.com" } ], "secrets": [ { "name": "DB_PASSWORD", "valueFrom": "arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:rds/myapp-db-AbCdEf:password::" } ] }

フェイルオーバーの動作確認と監視の設計

1. RDSのフェイルオーバーをテストする

RDSの手動フェイルオーバーを実行して、Proxy経由の接続切断時間を確認します。

【注意】force-failoverオプションはRDSのスタンバイへの即時切替を強制します。本番DBに対して実行すると一時的な接続切断が発生するため、必ずステージング環境で確認してください。

# RDSマルチAZのフェイルオーバーをテスト(ステージング環境で実施) aws rds reboot-db-instance \ --db-instance-identifier myapp-db \ --force-failover \ --region ap-northeast-1 # フェイルオーバー後のターゲット状態確認(Proxyが新しいプライマリを認識しているか) aws rds describe-db-proxy-targets \ --db-proxy-name myapp-proxy \ --region ap-northeast-1 \ --query 'Targets[].{Endpoint:Endpoint,TargetHealth:TargetHealth}'

直接接続の場合は切断が30~120秒続くことがありますが、Proxy経由では通常10秒以内に自動復旧します。これはProxyがRDSのDNS変更を検出して接続先を切り替えるためです。

マルチAZ冗長設計をシステム全体のアーキテクチャとして体系的に学びたい方は、AWSマスターセミナー上級編でVPC設計からフェイルオーバー設計まで実機ハンズオンで習得できます。

2. CloudWatchで接続数を監視する

RDS Proxyにはプロキシ専用のCloudWatchメトリクスがあります。

ClientConnections: LambdaなどクライアントからProxyへの接続数
DatabaseConnections: ProxyからRDSへの実際の接続数(コネクションプールの効果を数値で確認できる)
QueryDuration: クエリ所要時間(パフォーマンス監視)
ConnectionBorrowTimeout: 接続プールが満杯でクライアントが待機した回数(これが増えたらmax_connectionsPercent調整の合図)

ClientConnectionsとDatabaseConnectionsの比率が10:1以上になっていれば、コネクションプーリングが効いている証拠です。

# CloudWatchでClientConnectionsを確認(過去1時間の最大値) aws cloudwatch get-metric-statistics \ --namespace AWS/RDS \ --metric-name ClientConnections \ --dimensions Name=ProxyName,Value=myapp-proxy \ --start-time 2026-09-23T09:00:00Z \ --end-time 2026-09-23T10:00:00Z \ --period 300 \ --statistics Maximum \ --region ap-northeast-1 \ --query 'sort_by(Datapoints,&Timestamp)[*].{Time:Timestamp,Max:Maximum}' \ --output table

よくあるエラーと対処法

1. 「Access denied for user」がProxy経由で出る

ProxyのAuth設定とSecrets Manager内のDBユーザー名・パスワードが正しいか確認します。ProxyのStatusがavailableでも、シークレット内のパスワードが更新(ローテーション)されている場合は再認証に失敗します。

# Proxyが参照しているシークレットARNを確認 aws rds describe-db-proxies \ --db-proxy-name myapp-proxy \ --query 'DBProxies[0].Auth' \ --region ap-northeast-1

2. 「Connection timed out」が出てProxyに繋がらない

次の3点を順番に確認します。

・LambdaがProxyと同じVPC内のプライベートサブネットに配置されているか
・LambdaのSGからProxyのSGへポート3306のアウトバウンドが許可されているか
・ProxyのSGのインバウンドにLambdaのSGが含まれているか

VPC外のLambdaからプライベートSubnetのProxyへは到達できません。LambdaのVPC設定が未設定の場合は「LambdaとECSからRDS Proxyを使う設定」の手順を再確認してください。

3. Proxy経由でも「Too many connections」が出る

ProxyのターゲットグループにMaxConnectionsPercent(デフォルト100%)が設定されています。RDSのmax_connections全量をProxyが使い切っている状態です。インスタンスクラスのアップグレード、またはProxyを複数作成してターゲットグループを分割する設計を検討してください。

本記事のまとめ

Lambda・ECSとRDSの接続数問題はアーキテクチャの問題です。RDS ProxyをプライベートサブネットにマルチAZ配置することで、コネクションプーリングと自動フェイルオーバーの両方を解決できます。
やりたいこと 設計ポイント
Lambda同時起動による接続数爆発を解消する RDS ProxyでLambdaとRDSの間にコネクションプールを配置する
ProxyをマルチAZ配置する create-db-proxyの--vpc-subnet-idsに複数AZのサブネットを指定する
RDSへの直接接続を防ぐ sg-rdsのインバウンドをsg-proxyからのみ許可しLambdaからの直接接続を塞ぐ
DB認証情報を安全に管理する Secrets ManagerにシークレットをIAMロール経由でProxyに参照させる
フェイルオーバー切断時間を短くする Proxy経由で直接接続の30~120秒から10秒以内に短縮できる
プーリング効果を数値で確認する CloudWatchのClientConnections / DatabaseConnections比率を監視する
接続文字列のホスト名をProxyエンドポイントに変えるだけでLambda側のコード改修は不要なので、既存システムへの導入コストが低い点も RDS Proxyの利点です。

現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、Amazon LinuxとAWSを実務レベルで学べる無料マニュアルをご用意しています。AWSの設計を現場で自在に扱えるエンジニアになるために、まずは無料マニュアルをお受け取りください。

>> 無料マニュアルを受け取る

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録
宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として20年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。