コネクションプール

接続管理、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]
2mydb = host=127.0.0.1 port=5432 dbname=mydb
3
4[pgbouncer]
5listen_addr = 0.0.0.0
6listen_port = 6432
7
8; プールモード
9pool_mode = transaction
10
11; プールサイズ
12default_pool_size = 20
13max_client_conn = 1000
14min_pool_size = 5
15
16; タイムアウト
17server_idle_timeout = 600
18client_idle_timeout = 0
19
20; 認証
21auth_type = md5
22auth_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等)