2

HTTP インターフェイスを介してメッセージを受信する Web アプリケーションがあります。

http://server/application?source=123&destination=234&text=hello

このリクエストには、送信者の ID、受信者の ID、およびメッセージのテキストが含まれています。

このメッセージは次のように処理する必要があります。

  • ソースと宛先の両方に一致する User オブジェクトをデータベースから検索する
  • オブジェクトのツリーの作成: メッセージ テキスト用のフィールドと、ソースと宛先用の 2 つの User オブジェクトを含む Message
  • このツリーをデータベースに永続化します。

ツリーは、私が触れることができない他のアプリケーションによって読み込まれます。

Oracle をバッキング データベースとして使用し、JPA と Toplink をデータベース処理タスクに使用しています。可能であれば、私はこれらにとどまります。

多くの最適化を行わなくても、私の環境では最大 30 リクエスト/秒のスループットを達成できます。それほど多くはありません。1 秒あたり約 300 リクエストが必要です。そのため、パフォーマンスのボトルネックがどこにあるかを測定したところ、呼び出しにem.persist()ほとんどの時間がかかっていることがわかりました。その行を単にコメントアウトすると、スループットは 1000 リクエスト/秒をはるかに超えます。

簡単な JDBC 呼び出しを使用して同じデータベースに 100 万のメッセージを永続化する小さなテスト アプリケーションを作成しようとしました。バッチ処理を使用しました。つまり、100 回の挿入とコミットを行い、すべてのレコードがデータベースに入るまで繰り返しました。このシナリオで 1 秒あたり約 500 リクエストのスループットを測定しましたが、これは私のニーズを満たすものでした。

ここで挿入パフォーマンスを最適化する必要があることは明らかです。ただし、前述したように、純粋な JDBC ではなく、JPA と Toplink を引き続き使用したいと考えています。

JPA と Toplink を使用してバッチ挿入を作成する方法を知っていますか? JPA 永続化のパフォーマンスを向上させるための他の手法をお勧めできますか?

追加情報:

「リクエスト/秒」とは、リクエストの合計数 / テストの開始からデータベースに書き込まれた最後のレコードまでの合計時間を意味します。

em.persist()サーブレットとパーシスタの間にメモリ内キューを作成して、非同期呼び出しを試みました。パフォーマンスに大きく貢献しました。ただし、キューは非常に急速に増加し、アプリケーションは 1 秒あたり最大 200 のリクエストを継続的に受信するため、これは私にとって受け入れられる解決策ではありません。

この分離されたアプローチではem.persist()、トランザクションをコミットする前に、100 ミリ秒のリクエストを収集し、収集したすべてのアイテムを呼び出しました。EntityManagerFactory は、各トランザクション間でキャッシュされます。

4

2 に答える 2

3

JPAインターフェースから切り離し、ベアTopLinkAPIを使用する必要があります。おそらく、永続化しているオブジェクトをUnitOfWorkにチャックし、スケジュールに従ってUnitOfWorkをコミットすることができます(同期または非同期)。em.persist()のコストの1つは、オブジェクトグラフ全体で発生する暗黙的なクローンであることに注意してください。TopLinkは、2つのユーザーオブジェクトを自分でuow.registerObject()すると、かなりうまく機能し、それ以外の場合に実行する必要のあるIDテストを保存します。したがって、最終的には次のようになります。

uow=sess.acquireUnitOfWork();
for (job in batch) {
 thingyCl=uow.registerObject(new Thingy());
 user1Cl=uow.registerObject(user1);
 user2Cl=uow.registerObject(user2);
 thingyCl.setUsers(user1Cl,user2Cl);
}
uow.commit();

これは非常に古い学校のTopLinkです;)

バッチ書き込み、特にパラメータバインディングを使用したバッチ書き込みが開始されるため、バッチが非常に役立つことに注意してください。この単純な例では、パフォーマンスに非常に大きな影響を与える可能性があります。

その他の注意事項:シーケンスサイズ。TopLinkでオブジェクトを作成するために費やされる時間の多くは、特にデフォルトが小さい場合(シーケンスサイズとして数百以上になる可能性があります)、実際にはデータベースからシーケンス情報を読み取るために費やされます。

于 2008-09-15T20:03:25.957 に答える
0

「リクエスト/秒」の尺度は何ですか? つまり、31 番目の要求はどうなるでしょうか。ブロックされているリソースは何ですか? フロントエンド/サーブレット/Web 部分の場合、別のスレッドで em.persist() を実行してすぐに戻ることはできますか?

また、毎回トランザクションを作成していますか? リクエストごとに EntityManagerFactory オブジェクトを作成していますか?

于 2008-09-15T19:12:36.670 に答える