オンプレのDB接続構成

オンプレでは、APサーバー(Tomcat)内のHikariCPがDBへの接続プールを保持する構成が標準だ。

オンプレ:HikariCP → Oracle / PostgreSQL
Tomcat(4台)
  各台に HikariCP
    maximumPoolSize=20(各台あたり)
    合計接続数 = 4台 × 20 = 80接続 ← DBが受け付けられる範囲

Oracle / PostgreSQL
  max_connections = 200(全体上限)
  → 余裕あり

オンプレはサーバー台数が固定なので接続数が計算しやすい

コンテナ化で発生する接続数爆発

ECSでオートスケールが働くと、コンテナ台数が急増した際に接続数が一気に上限を超えるリスクがある。

接続数爆発のシナリオ
通常時:ECSコンテナ 10台
  10台 × HikariCP 20接続 = 200接続 ← Aurora上限付近

ピーク時:ECSコンテナが 30台にスケールアウト
  30台 × HikariCP 20接続 = 600接続 ← Aurora上限(例:500)を突破!

結果:
  新規DB接続が「接続数上限エラー」で失敗
  既存リクエストも影響を受けてサービス断

⚠️ Lambdaでは特に深刻

Lambda関数は同時実行数が数千になることがある。1関数あたり1接続でも、数千の同時接続がDBに殺到するとDB側がダウンする。RDS Proxyが最も効果を発揮するユースケースの一つだ。

RDS Proxyの役割

RDS ProxyはアプリとDBの間に立つ接続プールサービスだ。多数のコンテナからの接続をProxy側で束ね、Auroraには少数の接続のみを維持する。

RDS Proxy 介在時の接続構造
ECSコンテナ 30台
  各台 HikariCP 20接続
  → RDS Proxy へ 最大600接続

RDS Proxy(接続プール)
  → Aurora へは 例えば 50接続のみ維持
  (多重化して600接続を50接続に集約)

Aurora
  max_connections = 500
  → 余裕あり・安定動作

RDS Proxyが解決する3つの課題:

課題RDS Proxyの効果
コンテナスケールアウト時の接続数爆発 Proxy側でプール・多重化してAurora接続数を一定に保つ
Auroraフェイルオーバー時の接続エラー Proxyが接続を保持し新Primaryへ透過的に切り替え(アプリ側エラーを最小化)
Lambda等の瞬間的大量接続 Proxy側でバッファリングし、Aurora接続数を平滑化

AuroraのEndpoint設計(読み書き分離)

AuroraはWriter / Readerの2種類のエンドポイントを持つ。これをJava側で使い分けることで、参照系SQLをReaderに逃がしWriterの負荷を下げられる。

Aurora Endpoint の種類と使い分け
Cluster Writer Endpoint(例:cluster-id.cluster-xxx.ap-northeast-1.rds.amazonaws.com)
  → 書き込み(INSERT / UPDATE / DELETE)および即時整合性が必要な参照
  → フェイルオーバー後は自動的に新Primaryを指す

Cluster Reader Endpoint(例:cluster-id.cluster-ro-xxx.ap-northeast-1.rds.amazonaws.com)
  → 参照系SQL(SELECT)のみ
  → 複数Replicaにラウンドロビンで分散
  → 非同期レプリケーションのため、わずかな遅延あり(通常数ms〜数十ms)

RDS Proxy(推奨構成)
  ├── Writer Proxy Endpoint → Aurora Writer
  └── Reader Proxy Endpoint → Aurora Reader

HikariCPの設定変更点

RDS Proxyを導入しても、HikariCPの設定はほぼそのままでよい。接続先がAuroraの直接エンドポイントからProxyエンドポイントに変わるだけだ。

application.yml(RDS Proxy + 読み書き分離)
# 書き込みDS(Writer Proxy経由)
spring:
  datasource:
    primary:
      jdbc-url: jdbc:postgresql://${RDS_PROXY_WRITER_ENDPOINT}:5432/mydb
      username: ${DB_USER}
      password: ${DB_PASS}
      hikari:
        maximum-pool-size: 20
        connection-timeout: 30000
        keepalive-time: 60000   # Proxyのアイドルタイムアウト対策

# 読み取りDS(Reader Proxy経由)
    replica:
      jdbc-url: jdbc:postgresql://${RDS_PROXY_READER_ENDPOINT}:5432/mydb
      username: ${DB_USER}
      password: ${DB_PASS}
      hikari:
        maximum-pool-size: 20

# ポイント:
#   maximum-pool-size はProxyが多重化するので
#   オンプレ時より小さくしても問題ない

フェイルオーバー時の挙動比較

項目オンプレ(手動切り替え)AWS(Aurora + RDS Proxy)
フェイルオーバー検知監視ツール → アラート → 手動対応自動検知(数十秒〜約1分)
切り替え作業DNS変更 or VIP切り替え(手動)自動(Auroraが内部で実施)
アプリへの影響接続エラーが数分〜数十分続くRDS Proxy経由なら接続エラーを最小化
切り替え後の接続アプリの再起動が必要なケースありRDS Proxyが透過的に新Primaryへ誘導

💡 Aurora フェイルオーバーの速さ

Auroraのフェイルオーバーは通常30秒前後。さらにRDS Proxyを経由することでアプリ側の接続断が秒単位に短縮される。オンプレで手動切り替えをしていた頃の「数十分のダウンタイム」と比べると大幅な改善だ。

対比表

項目オンプレAWS
接続プールHikariCP(APサーバー内)RDS Proxy(インフラ層)+ HikariCP
読み書き分離アプリ設定で任意実装Aurora Writer / Reader Endpoint(構造として分離)
フェイルオーバー手動 or 独自スクリプト自動(約30秒・RDS Proxyで透過切り替え)
バックアップpg_dump等スクリプト自動バックアップ + PITR(ポイントインタイムリカバリ)
接続数上限管理台数×poolSize で手動計算・調整RDS Proxyが吸収・多重化
スケールアウト時の影響接続数超過のリスクありProxyが平滑化・Auroraは安定

ハマりポイント

⚠️ RDS Proxy と Prepared Statement のピン留め

RDS Proxyは接続の多重化(Multiplexing)を行うが、Prepared Statementを使用した場合、その接続が特定DBコネクションに「ピン留め」されて多重化が無効になる。PostgreSQL互換AuroraではuseServerPrepStmts=falseにすることでこの問題を回避できる。

⚠️ keepalive-time の設定が必要

RDS Proxyにはアイドルタイムアウト(デフォルト30分)がある。HikariCPのkeepalive-timeをProxy のタイムアウトより短く設定しないと、アイドル後の最初のリクエストで接続エラーが発生する。keepalive-time: 60000(1分)程度を設定しておくとよい。

次の記事では…

PART 06 では外部バッチからのDB処理を扱う。APとバッチが同じDBに接続することで起きる競合をどうアーキテクチャで解決するか、AWS Batch / Step Functionsの選び方を解説する。