JDBC を使用した接続プーリング オプション:DBCP 対 C3P0
-
21-08-2019 - |
質問
Java/JDBC で使用できる最適な接続プーリング ライブラリは何ですか?
私は 2 つの主な候補 (無料/オープンソース) を検討しています。
- アパッチ DBCP - http://commons.apache.org/dbcp/
- C3P0 - http://sourceforge.net/projects/c3p0
ブログや他のフォーラムでそれらについてたくさん読みましたが、決定には至りませんでした。
これら 2 つに代わるものはありますか?
解決
DBCP は期限切れであり、実稼働グレードではありません。少し前に、私たちは 2 つの社内分析を実施し、実際の条件下での適合性を評価するために 2 つに対して負荷と同時実行性を生成するテスト フィクスチャを作成しました。
DBCP は一貫してテスト アプリケーションに例外を生成し、C3P0 が例外なく処理できるパフォーマンス レベルに到達するのに苦労しました。
また、C3P0 は DB の切断と再開時の透過的な再接続を堅牢に処理しましたが、DBCP はその下からリンクが取り外された場合に接続を回復しませんでした。さらに悪いことに、DBCP は、基礎となるトランスポートが壊れているアプリケーションに Connection オブジェクトを返していました。
それ以来、私たちは 4 つの主要な高負荷コンシューマ Web アプリで C3P0 を使用してきましたが、過去を振り返ることはありませんでした。
アップデート: 長年棚に眠っていた後、Apache Commons の人々が DBCP が休止状態から復帰 そして今、再び活発に開発されているプロジェクトです。したがって、私の元の投稿は古くなっている可能性があります。
そうは言っても、私はこの新しくアップグレードされたライブラリのパフォーマンスをまだ体験していませんし、最近のアプリ フレームワークで事実上採用されているという話もまだ聞いていません。
他のヒント
ぜひ試してみてください ボーンCP -- 無料でオープンソースであり、利用可能な代替手段よりも高速です (ベンチマークのセクションを参照)。
免責事項:私は著者なので偏見があると言えるかもしれません :-)
アップデート:2010 年 3 月の時点でも、新しく書き直された Apache DBCP (「tomcat jdbc」) プールよりも約 35% 高速です。ベンチマークセクションの動的ベンチマークリンクを参照してください。
アップデート #2:(2013 年 12 月) 4 年間トップに君臨した後、今でははるかに速い競争相手がいます: https://github.com/brettwooldridge/HikariCP
アップデート #3:(9 '14) BoneCP は次のように考えてください。 廃止された 現時点では、に切り替えることをお勧めします ヒカリCP.
アップデート #4:(2015 年 4 月) -- 私はドメイン jolbox.com を所有しなくなりましたが、新しい所有者が古いコンテンツを保持しているので注意してください。
私はDBCPとのトラブルを抱えていました。私は生産にこれをリリースする予定が、その後のパフォーマンステストを開始しました。私はC3P0がひどく行われていることが分かりました。私は全然うまく実行するように設定することができませんでした。私はDBCPとして、それが二倍遅い見つけます。
私は、 Tomcatの接続プーリングを試みました。
この2倍の高速なC3P0ようだったと私はDBCPを持っていた他の問題を修正しました。私は3つのプールを調査し、テストに多くの時間を費やしました。あなたがTomcatにデプロイしている場合は私のアドバイスは、新しいTomcatのJDBCプールを使用することです。
DBCPと自動再接続の問題については、任意の以下の2つの構成パラメータを使用してみました?
validationQuery="Some Query"
testOnBorrow=true
今の生産で長年のカップルのためDBCPを使用しています。それは、安定しているDBサーバの再起動を生き残ります。ただ、それを適切に設定します。それだけで指定するパラメータの一握りを必要とするので、怠惰なことはありません。ここでは、明示的にそれを動作させるために設定したパラメータをリストし、当社のシステム製品コードからの抜粋です。
DriverAdapterCPDS driverAdapterCPDS = new DriverAdapterCPDS();
driverAdapterCPDS.setUrl(dataSourceProperties.getProperty("url"));
driverAdapterCPDS.setUser(dataSourceProperties.getProperty("username"));
driverAdapterCPDS.setPassword(dataSourceProperties.getProperty("password"));
driverAdapterCPDS.setDriver(dataSourceProperties.getProperty("driverClass"));
driverAdapterCPDS.setMaxActive(Integer.valueOf(dataSourceProperties.getProperty("maxActive")));
driverAdapterCPDS.setMaxIdle(Integer.valueOf(dataSourceProperties.getProperty("maxIdle")));
driverAdapterCPDS.setPoolPreparedStatements(Boolean.valueOf(dataSourceProperties.getProperty("poolPreparedStatements")));
SharedPoolDataSource poolDataSource = new SharedPoolDataSource();
poolDataSource.setConnectionPoolDataSource(driverAdapterCPDS);
poolDataSource.setMaxWait(Integer.valueOf(dataSourceProperties.getProperty("maxWait")));
poolDataSource.setDefaultTransactionIsolation(Integer.valueOf(dataSourceProperties.getProperty("defaultTransactionIsolation")));
poolDataSource.setDefaultReadOnly(Boolean.valueOf(dataSourceProperties.getProperty("defaultReadOnly")));
poolDataSource.setTestOnBorrow(Boolean.valueOf(dataSourceProperties.getProperty("testOnBorrow")));
poolDataSource.setValidationQuery("SELECT 0");
ここでDBCPはC3P0またはProxoolよりも大幅に高い性能を有することを示したいくつかの記事があります。また、私自身の経験をC3P0に準備された文のプールのように、いくつかの素晴らしい機能を持っているとDBCPよりも設定可能ですが、DBCPは、私はそれを使用しているどのような環境でもはっきり速くなります。
DBCPとC3P0の違いは?何もない! (堺開発者ブログ) <ストライキ> http://blogs.nyu.edu/blogs /nrm216/sakaidelic/2007/12/difference_between_dbcp_and_c3.htmlする ストライキ>
ブログの記事のコメントでJavaTechの記事「接続プール対決」にもなどを参照してください。
別の方法として、Proxoolは、この資料に記載されているのます。
あなたは、Hibernateはそのデフォルトの接続プールの実装にC3P0をバンドル理由を見つけることができるかもしれない?
残念ながら、彼らはすべての古くなっています。 DBCPは、他の2つは、多くの優秀なバグで、2〜3歳の、ビット最近更新されています。
DBCPは、生産準備ができています。
これは、例えば350000人の訪問者/日の商取引のウェブサイト上で200台の接続のプールで使用されます。
これは非常によく、あなたがそれを正しく設定してタイムアウトを処理します。
バージョン2進捗状況にあり、それは多くの以来、それは信頼性を向上させ、バックグラウンドを持っています 生産上の問題が取り組まれています。
私たちは、バッチサーバソリューションのためにそれを使用して、データベース内の行数百万人で作業バッチの数百を実行されています。
TomcatのJDBCプールが運営するパフォーマンステストは、それがCP30よりも優れた性能を持って示しています。
ただ、DBCPで一日半を無駄に行ってしまいました。私は、最新のDBCPのリリースを使用しているにもかかわらず、私がやったののjはpimmelとまったく同じ問題に遭遇しました。 DBが戻って来て、動的に戻ってプールに接続オブジェクトを追加することができないことは(それが永遠にハングアップしたとき、私は、特にそれがDBがなくなったときにプールから接続を投げるコツだ、全く再接続できないことをDBCPをお勧めしませんポストJDBCconnect I / Oソケット読む)
私は今、C3P0に切り替えています。私は、以前のプロジェクトでそれを使用しました、それが働いたと魔法のように行われます。
C3P0は良好です。私たちのプロジェクトでは、我々はより多くのスレッドの実行を使用した場合、我々は接続タイムアウトを持って、DBCPを使用することにより、同時に複数のスレッドの実行を使用していました。だから我々は、C3P0構成で行きました。
使いやすい良い代替は DBPOOL のです。
「Javaベースのデータベース接続プーリング・ユーティリティ、プールマネージャを使用して、時間ベースの満了、文のキャッシング、接続検証、及び簡単な構成をサポートする。」
接続プールを導入する必要がある状況に遭遇し、目の前には 4 つの選択肢がありました。
- DBCP2
- C3P0
- Tomcat JDBC
- ヒカリCP
当社の基準に基づいていくつかのテストと比較を実行し、HikariCP を選択することにしました。読む この記事 これが、私たちがHikariCPを選んだ理由を説明しています。
C3P0 を最良の方法で実装するには この答えを確認してください
C3P0:
エンタープライズ アプリケーションの場合、C3P0 が最適なアプローチです。C3P0 は、jdbc3 仕様および jdbc2 std 拡張機能で説明されているように、接続およびステートメント プーリングを実装するデータソースを含む、JNDI バインド可能なデータソースを使用して従来の (DriverManager ベースの) JDBC ドライバーを拡張するための使いやすいライブラリです。また、C3P0 は DB の切断と再開時の透過的な再接続を堅牢に処理しましたが、DBCP はその下からリンクが取り外された場合に接続を回復しませんでした。
これが、c3p0 やその他の接続プールにもプリペアド ステートメント キャッシュがある理由です。これにより、アプリケーション コードはこれらすべての処理を回避できます。通常、ステートメントは限定された LRU プールに保持されるため、一般的なステートメントは PreparedStatement インスタンスを再利用します。
さらに悪いことに、DBCP は、基礎となるトランスポートが壊れているアプリケーションに Connection オブジェクトを返していました。c3p0 の一般的な使用例は、Apache Tomcat に含まれる標準の DBCP 接続プーリングを置き換えることです。多くの場合、プログラマは DBCP 接続プール内で接続が正しくリサイクルされない状況に遭遇することがあります。この場合、c3p0 は貴重な代替品となります。
現在のアップデートでは、C3P0 にはいくつかの素晴らしい機能が追加されています。それらは以下に与えられます:
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setMinPoolSize();
dataSource.setMaxPoolSize();
dataSource.setMaxIdleTime();
dataSource.setMaxStatements();
dataSource.setMaxStatementsPerConnection();
dataSource.setMaxIdleTimeExcessConnections();
ここで、最大値と最小値は、 プールサイズ 接続の境界を定義します。これは、このアプリケーションが使用する最小接続と最大接続を意味します。 MaxIdleTime()
アイドル状態の接続をいつ解放するかを定義します。
DBCP:
このアプローチも優れていますが、接続タイムアウトや接続の再解放などの欠点があります。C3P0 は、マルチスレッド プロジェクトを使用する場合に適しています。私たちのプロジェクトでは、DBCP を使用して複数のスレッドを同時に実行しましたが、さらに多くのスレッドを実行すると接続タイムアウトが発生しました。そこで、c3p0 構成を採用しました。DBCP はまったくお勧めしません。特に、DB がなくなったときに接続をプールからスローする問題、DB が戻ってきたときに再接続できないこと、接続オブジェクトをプールに動的に追加し直すことができない (永久にハングアップする) という問題があります。 JDBCconnect 後の I/O ソケット読み取り)
ありがとう :)
私のおすすめは
ヒカリ > ドルイド > UCP > c3p0 > DBCP
これは私がテストした内容に基づいています - 20190202、私のローカルテスト環境(docker/poolの4GB mac/mysql minSize = 1、maxSize = 8)では、hikariは接続を取得するために1024スレッドx 1024回サービスを提供でき、各スレッドの平均時間終了までの時間は 100 万秒か 200 万秒ですが、c3p0 は 256 スレッド x 1024 回しか処理できず、各スレッドの平均時間はすでに 2100 万秒になっています。(512 スレッドが失敗しました)。