RDS の Too many connections を防ぐ方法 ── RDS Proxy で Lambda からの接続をまとめる

目次

概要

Lambda から RDS for MySQL に接続するアプリケーションで、アクセスが集中したときだけ Too many connections というエラーが出ることがあります。普段は問題なく動いているのに、キャンペーンやバッチの開始直後など、リクエストが一気に増えた瞬間に DB へつながらなくなる症状です。

原因は、DB インスタンスが同時に受け付けられる接続数(max_connections)を、クライアントの接続数が超えたことです。Lambda は同時に届いたリクエストごとに別々の実行環境で関数を動かすため、関数の中で DB に接続していると、同時実行数がそのまま DB への接続数になります。サーバー台数が決まっている EC2 のアプリケーションと違い、Lambda はリクエストに合わせていくらでも広がるので、小さな DB インスタンスの max_connections はすぐに埋まります。

この記事では、Too many connections が起きる仕組みと対処の選択肢を整理したうえで、RDS Proxy で接続をまとめる方法を確かめます。実践では、max_connections を小さく絞った RDS for MySQL に Lambda を 40 個同時に実行して実際にエラーを起こし、RDS Proxy を作って Lambda の接続先を切り替えると、同じ負荷でもエラーが消えることを確認します。最後に、CloudWatch の DB 側の接続数(DatabaseConnections)とプロキシが受け付けた接続の数(ClientConnectionsReceived)を並べて、プロキシが何をしているのかを数字で見ます。

Lambda の同時実行ぶんの接続を、RDS Proxy が少ない DB 接続にまとめる
Lambda の同時実行ぶんの接続を、RDS Proxy が少ない DB 接続にまとめる
クラウドおさる

猿山の長老会の部屋は椅子が 15 脚しかないのに、若い猿が 40 匹いっぺんに押しかけると、あぶれた猿は門前払いでござる。今日は、受付係を 1 匹置いて、順番に椅子を回してもらう方法を確かめるでござるよ。

この記事のメリット

  • Too many connections が起きる仕組み(max_connections と Lambda の同時実行数の関係)を説明できるようになる
  • max_connections を増やす・インスタンスクラスを上げる・Lambda の同時実行数を絞る・RDS Proxy を使う、といった対処の違いが分かる
  • RDS Proxy の接続プールと多重化が、DB への接続数をどう減らすのかが分かる
  • RDS Proxy を使うための前提(同じ VPC・2 つ以上の AZ のサブネット・Secrets Manager のシークレットまたは IAM 認証)と料金の単位が分かる
  • 実際にエラーを起こしてから RDS Proxy で直し、CloudWatch のメトリクスで効果を確かめる手順を体験できる

執筆者とキャラクター紹介

執筆者:土肥(とひ)

株式会社ジェニュインの代表であり元エンジニア。これまでオンプレミスと AWS 環境のインフラ業務を担当。AWS 認定資格の学習で得た知識を、ハンズオンとともに解説するのが得意。直近では新人の教育も行っており、これから技術を学ぶ方が納得できる解説を心がけています。基礎編・Cloud Practitioner の記事では、解説役としても登場します。

土肥

クラウドおさる

クラウドおさる

はじめましてでござる。弊猿はクラウドおさる。IT インフラが異常に発達した猿山から、雲に乗って地上の AWS を学びに降りてきたのでござる。

クラウドおさる

基礎編や Cloud Practitioner の記事では、とひさんに素朴な疑問をぶつける役でござるな。Security - Specialty などの記事では、要所でワンポイントや注意点をひとこと添えるでござる。

クラウドおさる

猿山にもデータセンターや監視当番があって、地上で起きることはだいたい猿山にも同じ仕組みがあるのでござる。例え話がつい猿山に寄るのは、弊猿の癖でござる。

技術解説

Too many connections が起きる仕組み

RDS for MySQL では、DB パラメータの max_connections が、同時に接続できるクライアントの数を決めます。デフォルト値は DB インスタンスクラスのメモリから計算され、MySQL では {DBInstanceClassMemory/12582880}(メモリの MB を 12 で割ったくらい)です。メモリの一部は OS と RDS の管理プロセス用に予約されるため、小さなインスタンスクラスほど少なくなり、たとえば db.t3.micro の MySQL では約 60 です。

クライアントの接続数が max_connections を超えると、MySQL では Too many connections、PostgreSQL では「残りの接続スロットは、レプリケートされていないスーパーユーザー接続用に予約されています」というエラーになります。

Lambda と組み合わせたときに起きやすいのは、Lambda のスケーリングの仕組みによるものです。

  • Lambda は、同時に処理するリクエストごとに、実行環境のインスタンスを別々に用意する
  • 関数の中で DB に接続すると、実行環境ごとに 1 本ずつ接続が開く
  • 同時実行数は、デフォルトではリージョン内の全関数で合計 1,000 まで広がる

つまり、同時に 40 件のリクエストが来れば、DB への接続も 40 本になります。max_connections が 15 の DB なら、16 本目以降はつながりません。

対処の選択肢

Too many connections への対処は、大きく次のように分けられます。

対処効き方注意点
使い終わった接続を閉じる・アイドル接続を減らす不要な接続が max_connections を食いつぶさないようにするまず既存の接続を見直すのが先。wait_timeout などのタイムアウトを大きくしすぎると、使っていない接続が残る
メモリの多い DB インスタンスクラスにスケールアップするmax_connections のデフォルト値が増える変更時にダウンタイムが発生し、料金も変わる
max_connections をデフォルトより大きくする受け付ける接続数を増やす接続ごとにメモリを使うため、デフォルトより大きくするのはベストプラクティスではない。メモリ不足でインスタンスが停止するおそれがある
Lambda の予約済み同時実行数で同時実行を絞る関数の同時実行数の上限が、そのまま接続数の上限になる上限を超えたリクエストはスロットリングされる
RDS Proxy を使う多数のクライアント接続を、少ない DB 接続にまとめるプロキシの料金がかかる。接続が「固定(ピン留め)」されるとまとめられない

AWS の公式の見解としても、max_connections を増やす前に既存の接続を見直すこと、増やすならスケールアップすること、アイドル接続が必要な構成なら RDS Proxy を使うことがベストプラクティスとされています。書き込みの急増なら、SQS でいったん受けてから一定の速さで DB に書き込む方法もあります(SQS でデータベースへの書き込みの急増を受け止める方法 ── 疎結合で DB を落とさない)。

RDS Proxy の仕組み

RDS Proxy は、アプリケーションと DB インスタンスの間に置くフルマネージドのデータベースプロキシです。アプリケーションは DB インスタンスのエンドポイントの代わりにプロキシのエンドポイントに接続します。接続の方法(ホスト名・ユーザー名・パスワード)は直接つなぐときと同じなので、多くのアプリケーションはコードを変えずに使えます。

RDS Proxy が接続数を減らす仕組みは、次の 2 つです。

仕組み内容
接続プーリングプロキシが DB への接続をプールしておき、使い回す。接続を開くたびにかかる TLS のハンドシェイクや認証のオーバーヘッド、接続ごとのメモリを減らせる
多重化(接続の再利用)1 つのトランザクションの間だけ DB 接続を割り当て、トランザクションが終わったら別のクライアントに回す。プロキシへのクライアント接続は多数開けたまま、DB への接続は少なく保てる
RDS Proxy の多重化:DB 接続はトランザクションの間だけ貸す
RDS Proxy の多重化:DB 接続はトランザクションの間だけ貸す

プール内の接続がすべて使われているときは、プロキシは新しいリクエストを待たせて順番に処理します。レイテンシーは増えることがありますが、DB が過負荷で突然落ちることはありません。待ち時間の上限は「接続借用タイムアウト」(最大 5 分)で決まり、それを超えるとタイムアウトエラーになります。

ただし、セッションの外で DB 接続を使い回すと安全でないとプロキシが判断した場合(16 KB を超えるステートメントなど)、そのセッションは最後まで同じ DB 接続を使い続けます。これを固定(ピン留め)と呼び、固定されたセッションでは多重化が効きません。CloudWatch の DatabaseConnectionsCurrentlySessionPinned で、固定がどれくらい起きているかを確認できます。

クラウドおさる

受付係が、話し合い 1 回ぶんだけ椅子を貸して、終わったら次の猿に回すのが多重化でござる。ずっと椅子を抱え込む猿(ピン留め)が増えると、回せる椅子が減ってしまうのでござるな。

RDS Proxy を使うための前提と料金

項目内容
対応エンジンRDS for MySQL・MariaDB・PostgreSQL・SQL Server(RDS for Oracle と RDS for Db2 では使えない)。使えるバージョンはリージョンごとに決まっている
ターゲット1 つのプロキシに関連付けられる DB インスタンスは 1 つ。レプリケーション構成では、リードレプリカではなくライターにだけ関連付けられる
ネットワークDB インスタンスと同じ VPC に置く。VPC には異なる AZ のサブネットが 2 つ以上要る。プロキシはパブリックにアクセスできない
DB への認証Secrets Manager のシークレット(DB ユーザーごとに 1 つ)を使うか、エンドツーエンドの IAM 認証(MySQL・PostgreSQL・MariaDB)を使う
クライアントの認証DB ユーザー名とパスワード、または IAM 認証。パスワードの方式(クライアント認証タイプ)は、RDS for MySQL では既定が MYSQL_CACHING_SHA2_PASSWORD。クライアントのドライバーがその方式で接続できないときは MYSQL_NATIVE_PASSWORD を選ぶ
接続数の上限「接続プールの最大接続数」(MaxConnectionsPercent)で、DB の max_connections の何 % までプロキシが使うかを決める
料金プロビジョニングされたインスタンスでは、プロキシを有効にした DB インスタンスの vCPU 数 × 時間(最低 2 vCPU 分)。Aurora Serverless v2 では ACU × 時間

プロキシにはパブリックにアクセスできないため、Lambda 関数は VPC に接続し、プロキシに届くネットワークに置きます(この記事では同じ VPC に置きます)。Lambda のドキュメントでも、単純な構成なら直接接続、本番環境では RDS Proxy を使う構成が勧められています。また、マルチ AZ 構成の DB インスタンスでは、RDS Proxy を通すことでフェイルオーバーのときも DNS の切り替えを待たずに新しいプライマリへ接続が回されます。

新卒・未経験の方へ
クラウドおさる

AWS を仕事にしたい方へ ── 新卒・未経験から

この記事を書いているのは、AWS の設計・構築を仕事にしている現役エンジニアです。運営元の株式会社ジェニュインでは、新卒・未経験の方も募集しています。異業種や文系からインフラエンジニアになり活躍しているメンバーもいます。

  • ✓システム開発・WEB エンジニア / インフラ構築などの職種で、未経験から応募できます
  • ✓未経験から入社した社員の声を含む社員アンケートを掲載
  • ✓応募フォームから 1 分で応募できます

実践

max_connections を 15 に絞った RDS for MySQL に、VPC 内の Lambda が直接接続している状態から始めます。まず Lambda を 40 個同時に実行して Too many connections を起こします。次に RDS Proxy を作り、Lambda の接続先をプロキシのエンドポイントに切り替えて同じ負荷をかけ、エラーが消えることを確かめます。最後に CloudWatch で、DB 側とプロキシ側の接続数を比べます。

前提条件

  • リージョン: ap-northeast-1(東京)
  • RDS・Lambda・Secrets Manager・IAM・CloudWatch・CloudShell の操作権限を持つ IAM ユーザーまたはロールでコンソールにログイン済みであること
  • アカウントの Lambda の同時実行数に、40 以上の空きがあること

以下のリソースが作成済みであることを前提とします。Lambda 関数 rds-proxy-lab-fn は、呼び出されるたびに環境変数 DB_HOST の接続先へ接続し、DB 側の接続 ID(CONNECTION_ID())を取ってから、接続を開いたまま 20 秒待って(外部 API の呼び出しなど、DB を使わない処理の代わり)接続を閉じます。接続できなかったときは、MySQL のエラーをそのまま返します。DB のユーザー名とパスワードは、シークレット rds-proxy-lab/db-admin から取ります。

まだ用意していない場合は、「作り方の参考」の記事の手順で作れます。リソース名は、この記事の名前に読み替えてください。

リソース種別リソース名内容作り方の参考
VPCrds-proxy-lab-vpcCIDR 10.20.0.0/16Amazon VPC で仮想ネットワークを構築しサブネットを設定する
プライベートサブネットrds-proxy-lab-private-1a / rds-proxy-lab-private-1c10.20.11.0/24(1a)/ 10.20.12.0/24(1c)同上 ※AZ を 2 つにする
セキュリティグループrds-proxy-lab-lambda-sgLambda 用。インバウンドなし同上
セキュリティグループrds-proxy-lab-proxy-sgプロキシ用。rds-proxy-lab-lambda-sg からの 3306 番を許可同上
セキュリティグループrds-proxy-lab-db-sgDB 用。rds-proxy-lab-lambda-sg と rds-proxy-lab-proxy-sg からの 3306 番を許可同上
DB パラメータグループrds-proxy-lab-mysql84ファミリー mysql8.4。max_connections を 15 に変更―
DB インスタンスrds-proxy-lab-dbRDS for MySQL 8.4、db.t4g.micro、シングル AZ、パブリックアクセスなし。マスターユーザー admin。パラメータグループ rds-proxy-lab-mysql84Amazon RDS でデータベースを作成し EC2 から接続する
シークレットrds-proxy-lab/db-adminadmin のユーザー名とパスワード(Amazon RDS データベースの認証情報)AWS Secrets Manager でシークレットを安全に保存しローテーションする
VPC エンドポイントSecrets Manager(インターフェイス型)VPC 内の Lambda からシークレットを取るため―
Lambda 関数rds-proxy-lab-fnPython。VPC の 2 つのプライベートサブネットに配置。環境変数 DB_HOST は rds-proxy-lab-db のエンドポイント、SECRET_ID は rds-proxy-lab/db-adminLambda から Secrets Manager のシークレットを取得する方法 ── ソースコードにパスワードを書かない ※VPC 内に置き、MySQL に接続する処理を足す

このハンズオンで作成するリソースは以下のとおりです。

リソース種別リソース名用途
RDS Proxyrds-proxy-lab-proxyLambda からの接続を受けて、rds-proxy-lab-db への接続をまとめる
IAM ロール(プロキシの作成画面で自動作成)RDS Proxy がシークレット rds-proxy-lab/db-admin を読むため

RDS Proxy は、作成している間ずっと、DB インスタンスの vCPU 数(最低 2 vCPU)× 時間で課金されます。DB インスタンス・VPC エンドポイント・シークレットも課金対象です。検証が終わったら必ず削除してください。

手順 1: max_connections と Lambda の接続先を確かめる

AWS マネジメントコンソールにログインし、リージョンが ap-northeast-1(東京)であることを確認します。上部の検索バーに RDS と入力し、「Aurora and RDS」を選択します。

左側ナビゲーションの「パラメータグループ」を選択し、rds-proxy-lab-mysql84 を開きます。パラメータの検索欄に max_connections と入力し、値が 15 になっていることを確認します。

rds-proxy-lab-mysql84 の max_connections が 15 になっている画面
rds-proxy-lab-mysql84 の max_connections が 15 になっている画面

続けて、左側ナビゲーションの「データベース」で rds-proxy-lab-db を開き、「接続とセキュリティ」タブの「エンドポイント」を控えておきます。

上部の検索バーに Lambda と入力し、「Lambda」を選択します。rds-proxy-lab-fn を開き、「設定」タブ →「環境変数」を選択します。DB_HOST が、控えておいた rds-proxy-lab-db のエンドポイントになっていることを確認します。いまは Lambda が DB インスタンスに直接接続している状態です。

手順 2: Lambda を 40 個同時に実行して Too many connections を起こす

コンソール上部の CloudShell アイコンから CloudShell を開き、次のコマンドで Lambda を同時に呼び出すスクリプトを作ります。40 個のスレッドから rds-proxy-lab-fn を同時に呼び出し、結果の種類ごとに件数を数えます。成功した呼び出しについては、DB 側の接続 ID ごとの件数も出します。

cat > burst.py <<'PY'
import json
from collections import Counter
from concurrent.futures import ThreadPoolExecutor

import boto3
from botocore.config import Config

client = boto3.client("lambda", config=Config(max_pool_connections=50, read_timeout=90))


def call(_):
    resp = client.invoke(FunctionName="rds-proxy-lab-fn", Payload=json.dumps({"hold": 20}))
    return json.loads(resp["Payload"].read())


with ThreadPoolExecutor(max_workers=40) as pool:
    results = list(pool.map(call, range(40)))

print("結果:", Counter(r.get("result") for r in results))
print("DB の接続 ID の種類:", len({r["connection_id"] for r in results if "connection_id" in r}))
PY

スクリプトを実行します。結果が出るまで 30 秒ほどかかります。

python3 burst.py

結果: の行に、OK と 1040 Too many connections の 2 種類が表示されることを確認します。OK は 13 件、1040 Too many connections は 27 件でした(実行ごとに多少前後します)。残りの呼び出しは max_connections を超えたため接続を断られています。DB の接続 ID の種類 は OK の件数と同じで、成功した呼び出しがそれぞれ別の DB 接続を使っていたことが分かります。実行した時刻を控えておきます(手順 6 でメトリクスを見るときに使います)。

CloudShell で burst.py を実行し、OK と 1040 Too many connections が混在している結果
CloudShell で burst.py を実行し、OK と 1040 Too many connections が混在している結果
クラウドおさる

40 匹のうち、椅子に座れたのは十数匹だけでござる。DB がまだ元気でも、椅子(max_connections)が埋まった時点で門前払いになる、というのがこのエラーの正体でござる。

手順 3: RDS Proxy を作る

RDS コンソールの左側ナビゲーションで「プロキシ」を選択し、「プロキシの作成」をクリックします。以下を設定します。

  • エンジンファミリー: MariaDB と MySQL
  • プロキシ識別子: rds-proxy-lab-proxy
  • データベース: rds-proxy-lab-db
  • 接続プールの最大接続数: 100(既定値のままです。このプロキシだけで DB を使うため)
プロキシの作成画面(エンジンファミリー・プロキシ識別子・データベース・接続プールの最大接続数)
プロキシの作成画面(エンジンファミリー・プロキシ識別子・データベース・接続プールの最大接続数)

認証と接続の設定は、以下のとおりにします。

  • デフォルト認証スキーム: なし(シークレットの認証情報で DB に接続します)
  • IAM ロール: デフォルトロールを作成(シークレットを読む権限を持つロールが作られます)
  • Secrets Manager のシークレット: rds-proxy-lab/db-admin
  • クライアント認証タイプ: MySQL Native パスワード(既定の MySQL Caching Sha2 パスワード のままだと、この記事の Lambda 関数(PyMySQL)はプロキシに接続できず 1045 Access denied になります)
  • IAM 認証: 許可されていません(Lambda はユーザー名とパスワードでプロキシに接続します)
  • サブネット: rds-proxy-lab-private-1a と rds-proxy-lab-private-1c(VPC のサブネットがあらかじめ入っているので、この 2 つになっていることを確認します)
  • VPC セキュリティグループ(「追加の接続設定」を開きます): rds-proxy-lab-proxy-sg(default が入っているので外します)

その他の項目はデフォルトのままにして、「プロキシの作成」をクリックします。

プロキシの作成画面(シークレット・IAM ロール・サブネット・VPC セキュリティグループ)
プロキシの作成画面(シークレット・IAM ロール・サブネット・VPC セキュリティグループ)

プロキシの作成には時間がかかります(検証では約 10 分)。rds-proxy-lab-proxy の状態が 利用可能 になったら、プロキシの詳細画面を開き、「プロキシエンドポイント」を控えておきます。エンドポイントは rds-proxy-lab-proxy.proxy-xxxxxxxx.ap-northeast-1.rds.amazonaws.com の形です。

プロキシが DB に接続できる状態かどうかは、ターゲットの状態で確かめます。CloudShell で次のコマンドを実行し、AVAILABLE と表示されることを確認します。REGISTERING や UNAVAILABLE の間は、プロキシ経由の接続は失敗します。プロキシが 利用可能 になった後も、しばらくは UNAVAILABLE(理由 PENDING_PROXY_CAPACITY)のままのことがあるので、AVAILABLE になるまで待ちます。

aws rds describe-db-proxy-targets --db-proxy-name rds-proxy-lab-proxy \
  --query 'Targets[].[RdsResourceId,TargetHealth.State]' --output text
rds-proxy-lab-proxy の詳細画面(状態が利用可能、プロキシエンドポイントが表示されている)
rds-proxy-lab-proxy の詳細画面(状態が利用可能、プロキシエンドポイントが表示されている)

手順 4: Lambda の接続先をプロキシのエンドポイントに変える

Lambda コンソールで rds-proxy-lab-fn を開き、「設定」タブ →「環境変数」→「編集」をクリックします。DB_HOST の値を、控えておいたプロキシエンドポイントに書き換えて、「保存」をクリックします。

環境変数の編集画面(DB_HOST にプロキシエンドポイントを入力した状態)
環境変数の編集画面(DB_HOST にプロキシエンドポイントを入力した状態)

変えたのは接続先のホスト名だけです。ユーザー名とパスワードは同じシークレットから取り、関数のコードも変えていません。

手順 5: 同じ負荷をかけて、エラーが消えたことを確かめる

CloudShell で、手順 2 と同じスクリプトをもう一度実行します。

python3 burst.py

結果: の行が OK の 40 件だけになり、1040 Too many connections が出なくなったことを確認します。DB の接続 ID の種類 は 40 より少なくなります(検証では 7 でした)。40 個の Lambda が、プロキシの持つ少ない DB 接続を順番に使い回したためです。こちらも実行した時刻を控えておきます。

CloudShell で burst.py を実行し、40 件すべてが OK になり、DB の接続 ID の種類が 40 より少ない結果
CloudShell で burst.py を実行し、40 件すべてが OK になり、DB の接続 ID の種類が 40 より少ない結果
クラウドおさる

押しかけた猿は同じ 40 匹でも、受付係が椅子を回してくれるから全員が用を済ませられたでござる。コードはそのままで、行き先の札(エンドポイント)を掛け替えただけなのが良いところでござるな。

手順 6: CloudWatch で DB 側とプロキシ側の接続数を比べる

上部の検索バーに CloudWatch と入力し、「CloudWatch」を選択します。左側ナビゲーションの「メトリクス」→「すべてのメトリクス」を選択し、「参照」タブで「RDS」→「データベース別のメトリクス」を選択します。rds-proxy-lab-db の DatabaseConnections にチェックを入れます。

「グラフ化したメトリクス」タブで、統計を 最大、期間を 1 分 にし、手順 2 と手順 5 の時刻が入るように表示期間を調整します。手順 2 のときは DatabaseConnections が max_connections(15)の手前で頭打ちになり(検証では 13)、手順 5 のときも 15 を超えずに収まっている(検証では 10)ことを確認します。手順 5 のあとも値が下がらないのは、プロキシがプールした DB 接続を開いたまま持っているためです。

rds-proxy-lab-db の DatabaseConnections のグラフ(手順 2 は 15 の手前で頭打ち、手順 5 も 15 以内に収まっている)
rds-proxy-lab-db の DatabaseConnections のグラフ(手順 2 は 15 の手前で頭打ち、手順 5 も 15 以内に収まっている)

続けて、「参照」タブで「RDS」→「プロキシごとのメトリクス」を選択し、ProxyName が rds-proxy-lab-proxy の ClientConnectionsReceived にチェックを入れます。統計を 合計、期間を 1 分 にします。手順 5 の時刻に、ClientConnectionsReceived(プロキシが受け付けたクライアント接続のリクエスト数)が 40 になっていることを確認します。

ClientConnections(現在のクライアント接続の数。1 分ごとに報告される)も見られますが、撮影時は 20 秒ほどで終わる今回の接続が数字に現れず、0 のままでした。短い接続の数を確かめるなら、受け付けたリクエストの数を数える ClientConnectionsReceived の合計が向いています。

rds-proxy-lab-proxy の ClientConnectionsReceived のグラフ(手順 5 の時刻に 40 になっている)
rds-proxy-lab-proxy の ClientConnectionsReceived のグラフ(手順 5 の時刻に 40 になっている)

2 つのグラフを並べると、プロキシの前(ClientConnectionsReceived)では 40 本の接続を受けながら、DB インスタンス側(DatabaseConnections)の接続は max_connections の範囲に収まっていることが分かります。なお、プロキシごとのメトリクスにも DatabaseConnections があり、こちらはプロキシから DB への接続数を表します。MaxDatabaseConnectionsAllowed(プロキシが使ってよい DB 接続の上限)と比べると、プールにどれだけ余裕があるかを確認できます。

クラウドおさる

「Lambda から RDS への接続が多すぎる」と来たら、まず RDS Proxy を思い出すでござる。max_connections を増やすのは椅子を詰め込むだけで、部屋(メモリ)は広がらない。プロキシは同じ VPC に置き、認証情報は Secrets Manager か IAM で渡す、ここまでを一緒に押さえるのでござる。

まとめ

要件・症状選ぶもの
Lambda の同時実行が増えると Too many connections が出るRDS Proxy で接続をプールし、DB への接続をまとめる
使っていない接続が max_connections を埋めている接続を閉じる処理とタイムアウトの見直し。アイドル接続が必要な構成なら RDS Proxy
DB の処理能力そのものが足りず、接続数も増やしたいメモリの多いインスタンスクラスへのスケールアップ
DB に届く同時実行数を関数側で抑えたいLambda の予約済み同時実行数(超えた分はスロットリングされる)
書き込みの急増を受け止めたいSQS でいったん受けて、一定の速さで書き込む
  • max_connections は同時に接続できるクライアント数の上限で、デフォルト値はインスタンスクラスのメモリで決まる。超えると MySQL では Too many connections になる
  • Lambda は同時に処理するリクエストごとに実行環境を用意するので、関数の中で DB に接続すると、同時実行数がそのまま DB への接続数になる
  • RDS Proxy は接続プーリングと多重化で、多数のクライアント接続を少ない DB 接続にまとめる。プールが埋まっているときはリクエストを待たせて順番に処理する
  • RDS Proxy は DB インスタンスと同じ VPC に置き、異なる AZ のサブネットが 2 つ以上要る。DB への認証には Secrets Manager のシークレットかエンドツーエンドの IAM 認証を使う
  • 料金はプロキシを有効にした DB インスタンスの vCPU 数 × 時間(最低 2 vCPU)。効果は DB 側の DatabaseConnections とプロキシ側の ClientConnectionsReceived を比べて確かめる

参照先

キャリア相談
クラウドおさる

独学の先に、AWS の仕事がある ── ジュニアおさるのキャリア相談

CLF には受かったけれど、次に何をすればいいのか分からない。独学で AWS を学ぶジュニアおさるの相談に、株式会社ジェニュイン代表の土肥が答えています。

  • ✓資格はゴールか、CLF の次に何から手を付けるか
  • ✓EC2 の次に作ってみる構成と、IaC・コスト管理
  • ✓実務経験ゼロでも、面接で話せる「これまで」の作り方
新卒・未経験の方へ
クラウドおさる

AWS を仕事にしたい方へ ── 新卒・未経験から

この記事を書いているのは、AWS の設計・構築を仕事にしている現役エンジニアです。運営元の株式会社ジェニュインでは、新卒・未経験の方も募集しています。異業種や文系からインフラエンジニアになり活躍しているメンバーもいます。

  • ✓システム開発・WEB エンジニア / インフラ構築などの職種で、未経験から応募できます
  • ✓未経験から入社した社員の声を含む社員アンケートを掲載
  • ✓応募フォームから 1 分で応募できます

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

株式会社ジェニュイン(https://genuine-pt.jp)の代表取締役.

2018年〜インフラエンジニアとしてキャリアをスタートし、オンプレミスのネットワーク・サーバ環境で3年半、クラウド環境で4年半の8年間エンジニアとして従事。
2021年に佐藤氏の創業した株式会社Luxyを引き継ぎ、代表に就任。
その後アガルートグループ内の株式会社ジェニュインと合併。
合併後同社代表に就任。

目次