1

大きな結果セットで選択を行うJavaバッチがあります(Springコールバックハンドラーを使用して要素を処理します)。callbackhandlerは、行を処理するためにタスクを固定スレッドプールに配置します。私のプールサイズは16スレッドに固定されています。結果には約100kの要素が含まれています。すべてのdbアクセスコードはJdbcTemplateまたはHibernate/Springを介して処理され、手動の接続管理はありません。AtomikosとCommonsDBCPを接続プールとして使用してみました。

さて、このバッチを終了するには、接続プール内の最大17の接続で十分だと思います。1つは選択用で、16は接続プール内のいくつかの行を更新するスレッド用です。ただし、最大プールサイズを1桁大きく指定する必要があるため(正確な値を試していません)、最初にローカルWindowsマシンで動作する50を試しましたが、そうではないようです。 Unixテスト環境では十分です。そこで、それを機能させるために128を指定する必要があります(ここでも、50から128の間の値を試していませんでしたが、直接128になりました)。

これは正常ですか?私が見逃している接続プールの基本的なメカニズムはありますか?開いた接続で何が起こるかを確認する方法がわからないため、これをデバッグするのは難しいと思います。さまざまなlog4j設定を試しましたが、満足のいく結果が得られませんでした。

編集、追加情報:接続プールのサイズが小さすぎると思われる場合、バッチがハングしているようです。プロセスでjstatを実行すると、すべてのスレッドが新しい接続を待機していることがわかります。最初は、dbcp接続プールでmaxWaitプロパティを指定しなかったため、スレッドは新しい接続で無期限に待機し、バッチがハングし続けていることに気付きました。したがって、接続は解放されませんでした。ただし、これは+ -70k行を処理した後にのみ発生し、接続リークの最初の兆候をなんとかして却下しました。

edit2:タスクの更新部分をすでに書き直したことを忘れました。ConcurrentLinkedQueueで更新を確認し、1000個の要素で更新を空にします。だから私は実際には約100回の更新しか行いません。

edit3:Oracleを使用しており、並行utilsを使用しています。したがって、16の固定プールサイズで構成されたエグゼキューターがあります。このエグゼキューターでタスクを送信します。タスクで接続を手動で使用するのではなく、スレッドセーフで接続プールからの接続を要求するjdbctemplateを使用します。Spring/DBCPが接続/スレッドの問題を処理すると思います。

4

2 に答える 2

1

Linux を使用している場合、MySQL を使用している場合は、MySql 管理者を試して、接続ステータスをグラフィカルに監視できます。

それにもかかわらず、1 分あたり数千の要求を処理する大規模なエンタープライズ アプリケーションでは、100 接続でさえ珍しくありません。

ただし、リクエストが少ない場合、または各リクエストが一意のトランザクションを必要としない場合は、スレッド内で操作を調整することをお勧めします。

つまり、100k の要素を 16 のスレッドにどのように分散させているのでしょうか? 共有ロケーション (またはバッファー) から行を読み取るたびに接続を取得しようとすると、時間がかかることが予想されます。

これが役立つかどうかを確認してください。

  1. getConnection
  2. バッファサイズがゼロになるまで各要素
  3. それを処理します。
  4. 更新が必要な場合は、
  5. 取引を開く
  6. アップデート
  7. トランザクションのコミット/ロールバック
  8. ステップ 2 に進みます
  9. 接続を解放する

java.util.concurrent コレクションを使用してバッファを同期できます

要素ごとに 1 つの Runnable/Callable を使用しないでください。これにより、パフォーマンスが低下します。また、どのようにスレッドを作成していますか?Executors を使用して実行可能/呼び出し可能を実行します。また、DB 接続がスレッド間で共有されることは想定されていないことにも注意してください。したがって、一度に 1 つのスレッドで 1 つの接続を使用します。

たとえば。Executor を作成し、それぞれが独自の接続を持つ 16 の runnalble を送信します。

于 2012-02-29T18:01:51.757 に答える
0

DBCP の代わりに c3p0 に切り替えました。c3p0 では、ヘルパー スレッドの数を指定できます。その数を使用しているスレッドの数と同じくらい高くすると、接続の数が非常に少なくなることに気付きました (c3p0 の便利な jmx Bean を使用してアクティブな接続を検査します)。また、それぞれ独自のエンティティ マネージャーとの依存関係がいくつかあります。どうやらエンティティ マネージャーごとに新しい接続が必要なようです。そのため、約 4 つのエンティティ マネージャー/スレッドがあり、これが接続数の多さを説明しています。c3p0 はより非同期で動作し、ヘルパースレッドの数を指定できるため、DBCP が接続を閉じたり解放したりすることができないほど、私のタスクはすべて短命であると思います。時間内に接続を解放することができます。

編集:しかし、バッチはテスト環境にデプロイされたときにハングし続け、接続を解放するときにすべてのスレッドがブロックされ、ロックはプールにあります。DBPCと同じです:(

編集:BoneCPに切り替えたときにすべての問題が解消され、ボーナスとしてパフォーマンスが大幅に向上しました

于 2012-03-02T08:15:35.800 に答える