5

メッセージが 1 時間あたり 70K XML の割合で受信し続けるアプリケーションがあります。これらの XML メッセージを消費し、中間キューに格納します。すべてのメッセージを 24 時間で消費するという SLA を満たす必要があるため、中間キューが作成されます。24 時間以内に XMLS を使用して内部キューにロードできます。内部キューにロードした後、XMLS を処理し (解析し、ほとんど変換を適用せず、ほとんど検証を実行しません)、データを高度に正規化されたデータ モデルに格納します。データモデルがパフォーマンスに大きな影響を与える可能性があることはわかっていますが、残念ながら、データモデルを制御することはできません。現在、2,000 件のメッセージを処理するのに 3.5 分かかっており、これは許容できません。2K メッセージの場合は 1 分に短縮したいと考えています。これまでに行ったことは次のとおりです。

1) 該当する場合は適用指数。
2) XML の解析に XMLBeans を使用します (各 XML のサイズはそれほど大きくありません)
3) 不要な検証、変換などをすべて削除し ました。

アプリケーションの実行環境:
オペレーティング システム: RHEL 5.4 64 ビット
プラットフォーム: JDK 1.6.0_17、64 ビット
データベース: Oracle 11g R2 64 ビット (2 ノード クラスター)
外部 MQ: IBM キュー
内部一時ストレージ MQ: JBoss MQ
アプリケーション サーバー: Jboss 5.1 .0.GA (EAP バージョン)

XML メッセージを消費して処理する順序は非常に重要であるため、並列処理を行うことはできません。

パフォーマンスを向上させるために他にできることはありますか?

4

2 に答える 2

4

これは [主要な] ボトルネックではないように思われるため、メッセージ配信の調整以外のいくつかの提案:

  • 高度に正規化されたデータベースにデータを保存していると述べました。これは常に、1 つ以上の参照データまたは PK ルックアップを意味し、このデータを取得するためにデータベースへの追加のトリップがいくつか作成されます。これを回避または削減するには、すべての参照データを含むローカル キャッシュを作成し、キャッシュを随時更新します。インメモリ ルックアップは、DB へのトリップよりも大幅に高速になります。
  • すべてのデコードと参照データをキャッシュするのに十分な RAM がないと感じた場合は、ディスクベースのキャッシュ (RAM、ディスク、またはオーバーフローを実行する EHCache など) を探すか、HyperSonic や H2 のような軽量のローカル DB を探してください。 Oracleへの旅行よりも倍(同じホストにいる場合を除き、それでも....)
  • 最終的に、各メッセージが DB へのラウンド トリップを何度も必要とする場合、メッセージの処理を DB 自体に移行すると、PL/SQL または Java でプロセスを実装できるようになります。
  • 処理される 1 つのメッセージのデータベースへの書き込みに複数の挿入/更新が含まれる場合は、必ず準備済みステートメントのバッチ処理を使用してください。これにより、DB への 1 回の呼び出しで複数の挿入/更新が送信されます。
  • プリペアド ステートメントについて言えば、Oracle 用のJBoss DataSource 設定が、処理中に作成されたすべてのプリペアド ステートメントを処理するのに十分な数値に設定されていることを確認してください (ゼロまたはキャッシュなしのデフォルトではありません)
  • 使用している XML パーサーは、小さなメッセージであっても (または特に) 必要以上のオーバーヘッドを課している可能性があります。JAXB を使用している場合は、アンマーシャラーを複数回 (または必要以上に) 再作成していないことを確認してください。または、プル/ストリーミング パーサーを試してください。DOM パーサーを使用している場合、追加のメモリが必要になるため、大量のガベージ コレクションが発生する可能性があります。
  • ばかげたことですが、言及する価値があります。メッセージごとに大量のログを実行している場合は、時間がかかるため、オフにしてください。
  • JBoss MQ を中間バッファーとして使用するのは洗練されていますが、持続性がより複雑であり、あらゆる種類の JMS メッセージ タイプに対して一般化されているため、遅延処理のためにメッセージを格納する最速の方法ではない可能性があります。JBoss MQ がとにかく Oracle に永続化されている場合、カスタムの永続化手順が高速にならない可能性は低いと思われます。JBoss MQ が (デフォルトで) HyperSonic に保存している場合でも、何らかのカスタム コードを使用すると、JMS メッセージの保存よりもパフォーマンスが優れている可能性があります。これはまた、処理のためにメッセージを DB から引き出すための新しいメカニズムが必要になることを意味しますが、JMS ストアと同様に、カスタム プロセスは JBoss MQ によって実装されるより一般化された手順よりも優れている可能性があります。
  • 中間メッセージを DB に保存すると、クエリの柔軟性が向上し、メッセージを逐次処理する必要がない場所を判断することもできます。(たとえば、異なるクライアントから発信されたメッセージは、順番に処理する必要はありません)。もちろん、中間メッセージに適切なヘッダーを配置することで、JBoss MQ でもこれを行うことができます。これにより、複数の異なるメッセージ リスナー/プロセッサで異なるセレクターを使用して並列化できます。

メッセージに関する 1 つの簡単な項目.....

WebSphere MQ でメッセージ駆動型 Bean を使用しているかどうかについては触れていませんが、使用している場合は、受信構成にpollingIntervalという設定があり、ドキュメントから引用すると、次のことを意味します。

セッション内の各メッセージ リスナーのキューに適切なメッセージがない場合、これは、各メッセージ リスナーがキューからメッセージの取得を再試行するまでに経過する最大間隔 (ミリ秒) です。セッション内のどのメッセージ リスナーでも適切なメッセージを使用できないことが頻繁に発生する場合は、このプロパティの値を大きくすることを検討してください。このプロパティは、TRANSPORT の値が BIND または CLIENT の場合にのみ関連します。

デフォルトのpollingTimeは 5000 ミリ秒です。現在のメッセージ処理時間は

(3.5 * 60 * 1000/2000)

= メッセージあたり 105 ミリ秒。

あちこちで 5000 ミリ秒の一時停止を導入すると、スループットが大幅に低下するため、メッセージのエンキュー時間とメッセージを受信する時間との継続的な差を測定することで、これを調べることができます。 JBoss メッセージリスナー。エンキュー時間は、次のメッセージ ヘッダーから判断できます。

  • JMS_IBM_PutDate
  • JMS_IBM_PutTime

全体として、最善の策は、並列化する方法を理解することです。

幸運を。

//ニコラス

于 2011-06-06T18:07:29.360 に答える
1

WebSphere MQ は、小規模なサーバーであっても、説明した速度よりもはるかに高速にメッセージをアンロードできます。WMQ V7のWindows パフォーマンス レポートは、クライアント チャネルで 1 秒あたり 2,200 を超える 2k の永続的なラウンド トリップ (1 つの要求と 1 つの応答) でテストされました。これは、1 秒あたり 4,000 件を超えるメッセージです。

あなたの場合のボトルネックは、メッセージの処理の待ち時間と、特定の順序でメッセージを処理することへの依存であるように思われます。最もパフォーマンスを向上させるオプションは、順序の依存関係を排除することです。私が銀行で働いていたとき、取引が到着した順序どおりに取引を記録するシステムがあり、誰もがこの要件は必須であると言いました。しかし、最終的にはシステムを修正して、日中にメモ投稿を実行し、後で再投稿するようにしました。メモの投稿は任意の順序で行われ、並列処理、フェイルオーバー、およびマルチインスタンス処理のその他すべての利点がサポートされていました。最後の投稿では、すべてのトランザクションが DB に格納された後、トランザクションを論理的な順序で (実際には、顧客にとって最も有利な順序で) 適用しました。シーケンスの依存関係はシングルトン モデルに閉じ込められ、非同期メッセージングの最悪のケースの要件です。可能であれば、それらを排除してください。

もう 1 つの改善点は、メッセージの解析と処理です。シーケンスの依存関係に悩まされている限り、これはパフォーマンスを向上させるための最善の策です。

最後に、より多くのメモリ、CPU、より高速なディスク I/O などの形で問題にお金を投じるオプションが常にあります。基本的に、これはソフトウェア アーキテクチャに馬力で対処することであり、決して最善の解決策ではありませんが、多くの場合、根本原因に対処するのに十分な時間を稼ぐことができます。

于 2011-06-03T14:35:04.473 に答える