コネクションプール
接続管理、PgBouncer、ProxySQL
コネクションプールはDB接続を再利用する仕組み。 接続の確立・切断コストを削減し、接続数を制限してDBサーバーを保護します。
なぜ必要か
プールなしの問題
- • 接続確立に数十ms〜数百msかかる
- • 各接続でメモリを消費(PostgreSQL: 数MB/接続)
- • 同時接続数の制限に達する
- • 短寿命接続の繰り返しでオーバーヘッド大
プールありの利点
- • 接続の再利用で高速化
- • DB側の接続数を制限
- • アプリケーションの接続数を柔軟に
- • 接続のヘルスチェック
プールの種類
アプリケーション内プール
各アプリケーションインスタンス内でプールを管理。 シンプルだがインスタンス数 × プールサイズ分の接続が必要。
例: HikariCP (Java), SQLAlchemy Pool (Python)
外部プロキシ(推奨)
アプリケーションとDBの間にプロキシを配置。 接続を集約し、DB側の接続数を大幅に削減。
例: PgBouncer (PostgreSQL), ProxySQL (MySQL)
外部プロキシの構成
App Servers (100インスタンス × 10接続 = 1000接続)
↓
PgBouncer (プール: 100接続に集約)
↓
PostgreSQL (max_connections: 150)
PgBouncer(PostgreSQL)
PostgreSQL用の軽量コネクションプーラー。低メモリで数千の接続を処理可能。
Session Pooling
クライアント切断まで同じ接続を使用。トランザクション外の状態を保持。
Transaction Pooling(推奨)
トランザクション終了後に接続を返却。最も効率的。
Statement Pooling
ステートメント終了後に返却。制限が多い(プリペアドステートメント不可)。
pgbouncer.ini
ini
1 [databases] 2 mydb = host=127.0.0.1 port=5432 dbname=mydb 3 4 [pgbouncer] 5 listen_addr = 0.0.0.0 6 listen_port = 6432 7 8 ; プールモード 9 pool_mode = transaction 10 11 ; プールサイズ 12 default_pool_size = 20 13 max_client_conn = 1000 14 min_pool_size = 5 15 16 ; タイムアウト 17 server_idle_timeout = 600 18 client_idle_timeout = 0 19 20 ; 認証 21 auth_type = md5 22 auth_file = /etc/pgbouncer/userlist.txt
ProxySQL(MySQL)
MySQL用の高機能プロキシ。コネクションプール、クエリルーティング、 読み書き分離、クエリキャッシュなどを提供。
コネクションプール
接続の多重化、アイドル接続の管理
読み書き分離
SELECTをレプリカに自動ルーティング
クエリルール
クエリパターンに基づくルーティング
クエリキャッシュ
頻繁なクエリの結果をキャッシュ
設定のポイント
プールサイズの決定
- • 小さすぎ: 接続待ちが発生
- • 大きすぎ: DBサーバーのリソース圧迫
- • 目安: CPUコア数 × 2 〜 4 程度
- • 実際の負荷でチューニング
Transaction Poolingの注意点
- • PREPARE文はトランザクション内で使用
- • SET文の効果はトランザクション終了で失われる
- • LISTEN/NOTIFYは使用不可
- • セッション変数に依存するコードは修正が必要
SRE/インフラ観点
監視項目
- • アクティブ接続数 / プールサイズ
- • 待機中のクライアント数
- • 接続の平均取得時間
- • サーバー側の接続数
高可用性
- • プーラー自体の冗長化(複数インスタンス)
- • ヘルスチェックの設定
- • フェイルオーバー時の接続切り替え
クラウド環境
- • AWS RDS Proxy、Cloud SQL Auth Proxy等も選択肢
- • サーバーレス環境では特に重要(Lambda等)