質問
次の点に関して、プールを設定する最良の方法は何ですか-
- いつ接続を作成しますか?
- いつ接続を閉じますか、またすべてを閉じますか?
- 接続がまだ良好であることをテストしますか。いつ、どのように?
- 接続の最大数に対する適切な数をどのように把握しますか?
- プールのユーザーの行動を保証するために、どのような監視を実施していますか? 1つの悪いコードがすべてを取り出すのを止められますか?
- 独自のプールを作成したか、サードパーティのライブラリを使用しましたか
これは不可知論的な質問だと思いますが、「機能」に関するコメントは特定のデータベース/言語の大歓迎です。たとえば、一部のデータベースへの接続は他のデータベースよりも遅いか、より高価になる場合があります。
明確にするために、私はゼロからプールを書くつもりはありません。この質問は、プーリングを行う既存のライブラリを構成する方法に関するものです。
解決
データベースの接続プールがJavaで作成されたのは、それが単なるデザインパターンであり、一般的なライブラリではない場合です。現在、Tomcatに組み込まれているものを使用しています。
スレッドを使用して、プールのいくつかの側面といくつかのパラメーターを監視して、その動作を制御しました...
- minimumInPool =" 3" ...これらの最初の3つは、起動時に作成されます。プールが3を下回ってはいけません。
- maximumIdleTimeBeforeRemoval =" 60" ...接続が1時間アイドル状態の場合、それをドロップして新しい接続を作成します。アイドル時間は、おそらくプールに最低3つしか存在しないことを意味します。
- maximumInUseTimeBeforeRemoval =" 30" ...特定の接続が30分以上チェックアウトされた場合、おそらく何かが間違っています。それを思い出して、接続を終了します。
- maximumTimeBeforeRemoval =" 60" ... 60分以上経過している場合は削除します。
- maximumUsageBeforeRemoval =" 1000" ... 1000回以上チェックアウトされている場合は削除します。
- monitorInterval =" 15" ...上記のパラメーターを15分ごとに確認します。
これは、数年間私に非常に役立ちました。私がこれまでに見た最高のプールは、野生のピーク時の151の接続でした。通常、プールは頻繁に使用されている間は約1ダースで、早朝には最低3つまでアイドル状態になりました。
OracleのJDBC Thinドライバを使用し、Oracleデータベースに接続しました。
他のヒント
最近の実装に使用した理論的根拠は次のとおりです。
-
接続プールに2種類の接続があります。最初のものは準備ができています。つまり、オープンですがクライアントによって使用されていないことを意味します。 2番目はアクティブで、クライアントによる使用を意味します。
-
接続プーリングで、最小数Nと最大数Mの少数のレディ接続を維持します。Nは、クライアントが接続を要求するピーク速度に応じて調整できます。レディ接続の数がゼロになった場合、Nを大きくする必要があります。数が常に大きい場合(10以上など)、Nを小さくする必要があります。
-
クライアントが接続を希望する場合、準備が整ったものの1つを与えて(アクティブにし)、準備がNに満たない場合はすぐに新しい接続を開きます(ただし、クライアントはこれを待たないでください)完了しないと、プーリングの利点が失われます)。これにより、常に少なくともN個の接続が準備できます。クライアントが必要なときに準備が整っていない場合、新しいクライアントを作成するまで待機する必要があります。
-
アクティブな接続でクライアントが終了すると、準備が整っている接続がM個未満の場合は、クライアントを準備完了状態に戻します。それ以外の場合は閉じます。これにより、M個を超える接続が準備できなくなります。
-
古い接続を防ぐために、準備完了の接続を定期的にリサイクルします。準備が整った接続がN個以上ある場合は、最も古い接続を閉じます。それ以外の場合は、閉じてからもう一度開きます。
これには、サーバーを過負荷にすることなく、接続プールで十分な数のおよび若々しい接続を利用できるという利点があります。
ジャカルタコモンズDBCPは、あなたがリストしたすべてのものをすでに実行しています:
- 必要に応じて接続を作成し、プールで管理します
- 一定期間使用されていない接続を閉じることができます
- 接続を渡す前に接続に対してクエリを実行できます。エラーがある場合、接続は破棄され、新しい接続が作成されます。接続はアイドル中に定期的にテストすることもできます。
- 作成される接続と、準備が整う接続の最小数に制限を設定できます。もちろん、制限はアプリケーションに大きく依存します。
- 方法はわかりませんが、DBCPは接続が閉じられていないことを認識し、それを閉じて例外をスローし、ログを見たときに何が起こったのかを知ることができます。
- DBCPには、非常に便利なタイムアウトパラメータがあります。プール内のすべての接続が使用されている場合、接続がプールに返されるまでその期間待機し、制限に達したときに使用可能な接続がない場合はエラーが発生します。
接続の最小数、作成する接続の最大数、およびタイムアウトで再生することにより、プールを微調整できます。タイムアウトを長くすると、接続の制限を低くすることができますが、タイムアウトを短くすると、おそらくより大きな数が必要になります。これは、アプリケーションの動作と接続の使用方法に大きく依存します。
マットbに同意します。車輪を再発明するべきではありません。
ただし、Commons DBCPの使用は、の回答に基づいて議論できます。これと this の質問。 そこには、 c3po やプロキシー。
または、rdbms依存接続プーリングメカニズムを使用できます。
私はあなたの接続を使用しているコンテキストがわかりませんが、私にとってはうまくいくと思われるものを共有できます。
SQLサーバーをバックエンドとして使用し、キャッシュと組み合わせてパフォーマンスを向上させています。 私の練習は、実際に必要な場合にのみ接続を開いたままにし、接続をすぐにクリーンアップしないように接続をプールしないことです.SQL Activityモニターでアクティブなものとそうでないものを正確に見ることができます。各接続はメモリを消費するため、必要のないときは鈍いar音をたてておくと便利です。
接続のオープンとクローズの質問に答える前に、キャッシュが本当に重要であると言います。キャッシュからオブジェクトを取得すると、時間を大幅に節約できます。開発中にキャッシュがオンになっているasp.netアプリのいくつかでは、レイテンシを測定することがほとんどできないのに対し、DBコールではコールを完了するのに15msから45msかかることがあり、これは考慮されていませんその他の遅延要因または負荷。私が使用するもう1つの方法は、データに適したオブジェクト構造なので、何かが変更された場合にのみDBを更新します。オブジェクトにいくつかのメソッドを実装しました。可能な限り少ないIOを実行するようにします。
このように、DBにアクセスして書き込む必要があることは誰もが知っているので、2つの原則に従います:
-
エネルギーを節約するために、ドアと窓は閉じたままにしてください。ある場所で開いている接続とは、別の場所では使用できないことを意味します(またはメモリや他のリソースがより制限されています)。パフォーマンスが向上したため、プーリングをオフにしました。
-
接続が開いているときにできる限りバッチで、または一度に処理します。これはもう少し複雑なので、説明しましょう。
- 私が使用した1つの方法は、すべてのオブジェクトが1つの接続オブジェクトを使用できるように、パイプに接続オブジェクトを渡すことです。これにより、アプリによっては10以上の接続ではなく、1つの接続が開いたり閉じたりします。これの良い例は、統計を収集し、複雑な順序パターンをハッシュ化するためにSQLサーバーの能力を利用する購入モデルの1つです。 20万件以上のDBルックアップなど、アプリの用途が何であれ、接続を開いたり閉じたりすることは意味がありません。これの他の部分は、オブジェクトを使用するとき、接続を開いたままにする時間を短縮するために更新をバンドルしようとすることです。したがって、挿入呼び出しでscope_identityを実行すると、挿入と、キャッシュする前にオブジェクトに追加する一意のIDのルックアップの両方を処理できます。 aspアプリを最初に開発していた頃、ページの読み込みが開始されたらすぐに接続を開き、その後閉じます。もうこれを行うことはお勧めしません。ある日、これらの種類の抽象化とレイヤーには大きな恩恵があります。初心者プログラマーに注意を払うことをお勧めします。
私の2セント:
データをキャッシュします!データをキャッシュします!データをキャッシュします!キャッシュできず、データをキャッシュできない場合は、できるだけDBアクセスを少なくしてください!