JDBCプールの説明

Explaining jdbc-pool, a High Concurrency Alternative to Connection Pooling Module | TomcatExpert

この記事ではTomcat開発主幹で開発されているモジュールの一つを探る。
JDBCプールは名前の通りJDBCリソースのプーリング実装である。

コネクションプールは古くから存在している。
1997年Javaを初めて知った時に私自身が書いており、
そして私が働いていた別のプロジェクトの中で長く使っていた。

JDBCが出現したとき、JDBCコネクションのプーリングがパフォーマンス上
有益であること、そしてサイフォンコネクションとデータベースサーバの
リソース制御の一つの方法であることを、開発者達は理解した。

常にデータベースがオーバーロードの危険にさらされている
水平統合されたクラスタにおいて、これは特に重要である。

当時はAPサーバを1CPUか2CPU、多くても4CPU程度の
マシンで運用するのが一般的だった。

J2EEベンダはトランザクション処理に統合するため
コネクションプーリングを早くに内製した独自のものを
自分たちのサーバに統合した。

J2EEコンテナのほかに、たくさんのオープンソースプロジェクトが立ち上がった。
Proxool, Apache Commons DBCP, C3P0 and Poolmanなどである。
これらはこの分野における最も一般的なものである。

Apache Tomcatはユーザにコネクションプールの実装を提供するために
非常に長いあいだDBCPに依存してきた。

これらのオープンソースプロジェクトのすべてに良い点と悪い点がある。
しかしそれらにはすべて共通したことがある。

これらのプロジェクトの動きはかなり停滞しており、
そのコード基盤はJava言語における新機能を満たせるほど進化できていない。
Javaアプリケーションの展開における一般的なプラットフォームとなった
マルチコアのハードウェア用に最適化されない。

プロジェクトのいくつかはソースコード中の不必要な煩雑さに悩まされている。
最もありがちな主要原因の一つはプロジェクトコードが前進し続けないこと、
維持管理が難しくなること、壊れやすくなることである。

以上のプロジェクトの他にも4つのオープンソースプロジェクトに言及する。

今日のApache Tomcatの展開で私達が目にすることができる2つは
Commons DBCP と C3P0である。
これら2つのプロジェクトの短い要約は以下の通り。

Commons DBCP
Apache Tomcatと一緒に発送。とても利用しやすいのでよく使われている
・とても安定したコードベース
・長年にわたってデッドロックに悩まされていた
・低いクロックスピートだが高い並列処理をする顧客が
 スループットボトルネックについてしばしば文句を言っている。

C3P0
・DBCPの代わりに良く使われている
・フィールドでの経験に基づいており、まだまだバグがいっぱい
・DBCPよりもパフォーマンスがよいという評判があるが、
 わたしたちの検証結果ではそうでもない

これらの実装はどちらも非常にややこしい。
DHCPApache Commons Poolプロジェクトのトップレベルでビルドされていて、
60以上のソースファイルのコードベースと全部一緒になっている。
C3P0 は200を超えるソースファイルに成長した。

どちらのプールも以下に言及するようないまいちな特徴がある。

・プールはJavaのバージョンと静的に結びついている。
 Java5で記述されたプールは、Java6のjava.sqlとjavax.sqlインタフェースと
 互換性がない。ユーザが最新のインターフェースメソッドを実行しようとすると
 NoSuchMethodExceptionを受け取ってしまう。
・プールはjava.sql.ドライバインタフェースに制限されている。
 このためjavax.sql.データリソースからリソースをプールすることが不可能。
・XAデータソースをサポートしていない。
・新機能をプラグインするための柔軟性がない。

わたしたちの問題に戻ると、なぜ他にプールのプロジェクトを行うのか?
その答えはシンプルで、より良いパフォーマンスと高機能が必要だからである。
わたしたちはまた、レガシーな実装の一つを採用することは
コードベースの大部分の書き直しを必要とするだろうと思っている。
だから、われわれは60以上、または200以上のソースを書き換えても
いいかどうかジャッジメントコール(審議)をすることになった。

現存するコードベースに貢献するよりも最初からrewriteほうがいいと
考える人もいるかもしれない。
ほとんど全ての場合において、rewriteよりもreuseとfixのほうが望ましい。
しかしながら、以下のような質問をちゃんと審議したうえで行うべきである。

・Commons DBCPの全く同じ実装を提供するために何ラインのコードが必要なのか。
java.sql.の全てのメソッドの公開に対応できるような柔軟な実装が可能なのかどうか。
・追加機能の公開に対するフレームワークを提供できるのかどうか。
・マルチコア環境における実装をすることができるのかどうか。

Apache Software Foundationのなかにあって直面する次の問題は
このプロジェクトまわりのコミュニティをどのように作るかである。
コミュニティは、円満に終わらない多くのコードをもつことによって成長するものである。

そこには複数の領域のなかでやり遂げなければならないことがあり、
それはそれで一緒に活動するためのグループにとって楽しいものである。

すでにわたしたちはプロトタイプを作成していた。
プロトタイプは8つのソースファイルでできており、
別のプールを結合する全ての機能を提供するプロトタイプだ。
Java開発者のグループをそれほど興奮させるものではない。

それぞれのプロジェクトの火を消すことは
コミュニティの視点からみて実りがあることではない。

わたしたちはそれ以後、ソースファイルを24に成長させた。
これらのソースファイルはほとんどが設定しやすい
プレビルドアドオンを作った。

このようにしてjdbc-poolモジュールは開始された。

jdbc-poolは早く採用され、バグの数も非常に少なかった。
最も早いバグは java.sqlインタフェースの典型的な利用についての
現実的な回避策だった。
コネクション上のclose multiple timesと呼ばれている。

現在jdbc-poolはまだリリース前の段階だけれども、
製品利用されている実験がある。
SpringSourceはプールモジュールを彼らのサーバ製品と一緒に
出荷している。その情報はブログで得ることができる。

jdbc-poolは簡単に移行(マイグレーション)できるように
CommomsDBCPとほとんど同じ構造をしている。
Apache TomcatとDBCPを使っているユーザにとっては、
factory属性の違いだけである。
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"

dependency injection frameworksのユーザは、
Spiring Frameworkのように、
org.apache.tomcat.jdbc.pool.DataSource bean.を
設定するだけである。

JDBCコネクションのための別のプールモジュールはまだない。
この後の記事で、わたしは掘り下げて説明する。

jdbc-poolのパフォーマンス
・機能、その機能をいつどのように使うか
・実際の実装と、なぜそのように見積もられるのか
・どのように拡張機能をつくるか