# Webシステムにおけるデータベース接続アーキテクチャ概論
[[Yuuki Tsubouchi]](y_uuki)が2015年6月30日にゆううきブログで公開した技術記事。主に新卒Webエンジニア向けに、Webアプリケーションサーバとデータベースサーバとのあいだの接続管理モデルと運用事情を体系的に解説する。前作「2015年Webサーバアーキテクチャ序論」の続編。PerlとMySQL、ScalaとPostgreSQLの組み合わせを実際に運用した経験に基づく。
## 背景と問題意識
コネクションプーリングは「サイエンスになるほどの理論はないが定番のノウハウはある」(@kuenishi 2013)とされており、体系化されたドキュメントが少ない。特定のDB製品・クライアント実装・ワークロードに限定した話に振り回されがちな領域だった。
## データベース接続のオーバヘッド
RDBMSの接続には複数層のオーバヘッドが積み重なる:
- **TCPコネクション確立**: 3-way handshakeのレイテンシ
- **データベース層ハンドシェイク**: MySQLはConnection Phase、PostgreSQLはMessage Flowで規定
- **認証**: データベース層の認証シーケンス
- **プロセス/スレッド生成**: データベースサーバ側のリソース消費
加えて、都度接続ではTCPウィンドウサイズが毎回初期値から始まるため、常時接続と比べてネットワークスループットが低下する。
> C/S型のRDBMSは元々少数のクライアントとステートフルな通信を行うために設計されていることが多く、HTTPのように多数クライアントと接続切断を繰り返す方式とはインピーダンスミスマッチがある(@kazuho 2013)。
## 接続モデルの3分類
### リクエスト都度接続モデル
リクエスト処理中のみ接続を維持し、終了時に破棄する。Plack::MiddlewareやScope::Container::DBIなどでフック可能。オブジェクト管理が比較的容易。
### 常時接続モデル
グローバル空間にDBハンドラオブジェクトを保持し、後続リクエストでも使いまわす。PreforkモデルのWebサーバでは各ワーカープロセスがそれぞれ保持する。
**デメリット**:
- リソースリーク(メモリリーク)の温床
- 切断検出と再接続の実装が必要
- L4ロードバランサ(LVS/HAProxy)経由では均等分散が困難(接続が切れないため振り分け先固定)
- DBフェイルオーバ時の再接続に時間がかかる
PerlのDBIでは `connect` の返り値をそのままキャッシュしてもうまく動かない。`connect_cached` や `Scope::Container::DBI` を使うこと。
### コネクションプーリング
常時接続の発展形。接続を永続化しながら接続数を厳密に管理する。詳細は[[コネクションプーリング]]を参照。
## PostgreSQL vs MySQL の接続事情
| 項目 | PostgreSQL | MySQL |
|------|-----------|-------|
| 接続モデル | 1接続=1プロセス(マルチプロセス) | 1接続=1スレッド(マルチスレッド) |
| 接続オーバヘッド | 大きい(fork コスト・プロセスメモリ) | 小さい(Thread Cacheで再利用) |
| 推奨接続方式 | プロキシ型プーリング([[PgBouncer]]・[[Pgpool]])| 都度接続が多い |
| 実績事例 | Instagram → [[PgBouncer]]採用 | Mobage・[[Hatena]] → 都度接続 |
PostgreSQLはCoW最適化があるものの、fork元プロセスとの乖離が進むにつれてプロセスあたりのメモリ消費が増加する。大量接続時に負荷が急増するため、[[PgBouncer]](イベント駆動型・軽量)または[[Pgpool]](高機能・Preforkモデル)との併用が標準的。
## 運用上の知見
- 接続を永続化するとL4ロードバランサによる均等分散が難しくなる。メンテナンス時はコネクションの重みを0にして切れるのを待つ必要がある。
- フレームワーク変更(例: モダンPerlからPlay2)でデフォルトの接続方式が変わることがある(都度接続 → 常時接続)。
- 無理にコネクションプーリングを実装するより、DBのスケールアップ/アウトで解決できるならそのほうが単純。
- アプリとオペレーション両方の視点が必要な領域(DevOpsの一環)。
## 関連
- 核心概念: [[データベース接続モデル]] / [[コネクションプーリング]]
- 関連エンティティ: [[Yuuki Tsubouchi]] / [[PgBouncer]] / [[Pgpool]] / [[Hatena]]
- 関連記事(著者による): ゆううきブログ「2015年Webサーバアーキテクチャ序論」