コネクションプーリング
コネクションプーリングとは
コネクションプーリングは、データベースへの接続(コネクション)をあらかじめ複数作って使い回す仕組みです。プール(たまり場)に接続を待機させておき、必要なときに貸し出し、使い終わったら切断せずプールに返します。
なぜ使い回すのか。データベースへの接続確立は、TCP接続、認証、サーバー側のプロセス・メモリ確保など、見た目以上に重い処理だからです。リクエストのたびに接続と切断を繰り返すと、肝心のクエリより接続処理に時間を食われてしまいます。
仕組み
アプリ ──借りる──> [ 接続プール(例: 10本の接続を維持) ] ──確立済み──> DB
<──返す────
- アプリはプールから接続を借りてクエリを実行し、終わったら返す
- プールが空(全部貸出中)のときは、空くまで待つかエラーにする
- [[ORM]] や各言語のDBライブラリには、たいていプール機能が組み込まれている(HikariCP、pgbouncer などの専用ツールもある)
プールサイズの考え方
「多いほど速い」わけではないのが要注意ポイントです。
| プールが小さすぎる | プールが大きすぎる |
|---|---|
| 接続待ちが発生しアプリが詰まる | DB側のメモリ・CPUを食い潰す |
| 同時実行が増えすぎて逆に遅くなる |
データベース側にも最大接続数の上限(max_connections)があります。[[Webサーバーとアプリケーションサーバー]] を複数台に増やすと「台数 × プールサイズ」の接続がDBに集中するため、[[スケーリング]] の際は上限との整合を必ず確認します。
初学者向けポイント
- 「接続を借りたら必ず返す」がアプリ実装の鉄則 — 返し忘れ(リーク)が積み重なるとプールが枯渇し、システム全体が停止する。try-finally やフレームワークの自動管理に任せる
- [[サーバーレス・Lambda]] の環境([[リレーショナルデータベース]] に多数の実行環境から接続する構成)ではプールが効きにくく、pgbouncer のような外部プロキシ型プールを挟むのが定番
- 「DBが too many connections エラーを出す」「アプリが応答しない」— どちらもまずプール設定を疑う。プールに空きがあるのに遅いなら [[実行計画とクエリチューニング]] 側を見る
関連技術とのつながり
- [[リレーショナルデータベース]] — 接続コストが高いDBほどプールの恩恵が大きい
- [[ORM]] — 多くのORMがプール機能を内蔵している
- [[Webサーバーとアプリケーションサーバー]] — プールはアプリサーバー側に置かれる
- [[スケーリング]] — サーバー台数×プールサイズとDB上限の整合が必要
- [[エラーハンドリングとリトライ設計]] — 待ち時間の上限と確実な返却が枯渇を防ぐ
Q: コネクションプーリングが解決する問題はどれ?
- [x] リクエストのたびに重い接続確立処理を繰り返す無駄
- [ ] SQL の文法エラー
- [ ] テーブル設計の正規化不足
解説: 接続確立は TCP・認証・リソース確保を伴う重い処理のため、確立済みの接続を使い回して高速化します。
Q: プールを大きくしすぎたときに起こることとして本文で挙げたのはどれ?
- [ ] 接続待ちが増えてアプリが詰まる
- [x] DB側のリソースを食い潰し、逆に遅くなることがある
- [ ] データが自動的に削除される
解説: 接続数が増えるほど DB のメモリ・CPU を消費し、同時実行が増えすぎて性能が落ちることがあります。
Q: 接続の「返し忘れ」が積み重なると何が起きる?
- [ ] プールが自動的に2倍に拡張される
- [ ] 古いデータが上書きされる
- [x] プールが枯渇して新しい処理が接続を借りられなくなる
解説: 返却漏れ(リーク)でプールが枯渇すると、待ちが連鎖してシステム全体の停止につながります。