さまざまなサービスを通じてメッセージを処理します(1つのメッセージは、完了する前におそらく9つのサービスに触れ、それぞれが特定のIO関連機能を実行します)。現在、パフォーマンスに関して最悪のケース(XMLデータコントラクトシリアル化)とベストケース(メモリ内MSMQ)の組み合わせがあります。
メッセージの性質は、シリアル化されたデータが約12〜15キロバイトになり、週に約400万のメッセージを処理することを意味します。MSMQの永続メッセージは私たちにとって遅すぎました。データが大きくなるにつれて、MSMQのメモリマップファイルからのプレッシャーを感じています。 サーバーのメモリ使用量は16 GBで、キューイングのためだけに増加しています。 メモリの使用量が多い場合、マシンがスワップを開始するため、パフォーマンスも低下します。既にMSMQの自己クリーンアップ動作を実行しています。
ここで間違っている部分があるように感じます。RavenDBを使用してメッセージを永続化し、識別子をキューに入れようとしましたが、パフォーマンスは非常に遅くなりました(せいぜい毎分1000メッセージ)。それが開発バージョンを使用した結果なのかどうかはわかりませんが、より高いスループットが必要です[1]。コンセプトは理論上は非常にうまく機能しましたが、パフォーマンスはタスクに応じていませんでした。
使用パターンには、すべての読み取りを行うルーターとして機能する1つのサービスがあります。他のサービスは、サードパーティのフックに基づいて情報を添付し、ルーターに送り返します。ほとんどのオブジェクトは9〜12回タッチされますが、約10%は、サードパーティが適切に応答するまで、このシステムでしばらくループすることを強制されます。この理由でメッセージの優先度フィールドを使用するため、サービスは現在これを考慮しており、適切なスリープ動作を持っています。
だから、私の質問は、C#/ Windows環境でディスクリートだがLAN接続されたマシン間でメッセージを渡すための理想的なスタックは何ですか? 通常、XMLシリアル化ではなくBinaryFormatterから始めますが、シリアル化をドキュメントストアにオフロードするのがより良い方法である場合、それはうさぎの穴です。したがって、私の質問。
[1]:私たちのビジネスの性質は、メッセージをより早く処理するほど、より多くのお金を稼ぐことを意味します。週の後半にメッセージを処理すると、そのお金を稼ぐ可能性が低くなることを経験的に証明しています。「1分あたり1000」というパフォーマンスは非常に高速に聞こえますが、実際にはその数が10k /分以上必要です。1週間あたりのメッセージ数を指定しているからといって、それらのメッセージを処理するのに1週間あるというわけではありません。
===============編集:
追加情報
コメントに基づいて、いくつかの説明を追加します。
シリアル化がボトルネックであるかどうかはわかりません。アプリケーションのベンチマークを行ったところ、シリアル化はヒートグラフに表示されますが、サービスのCPU使用率の2.5〜3%にしか関与していません。
私は、私たちのメッセージの永続性とMSMQの潜在的な誤用についてほとんど心配しています。キューのパフォーマンスを維持できるように、非トランザクション、非永続メッセージを使用していますが、少なくとも永続メッセージが再起動後も存続できるようにしたいです。
RAMを追加することは一時的な対策です。マシンはすでに4GBから16GBのRAMに移行しており、追加を続けるためにマシンを停止することはますます難しくなっています。
アプリケーションのスタールーティングパターンにより、オブジェクトがポップされてからキューにプッシュされる時間の半分は、まったく変化しません。これは、他の場所の何らかのキー値ストアにそれを保存し、メッセージ識別子を単に渡すことに再び役立ちます(IMO)。
スタールーティングパターンはアプリケーションに不可欠であり、変更されません。途中のすべてのピースが非同期に(ポーリング方式で)動作し、再試行動作を1か所に集中させたいため、アプリケーションをムカデにすることはできません。
アプリケーションロジックはC#で記述され、オブジェクトは不変のPOCO、ターゲット展開環境はWindows Server 2012です。特定のソフトウェアがLinuxでのみサポートされている場合、追加のマシンを立ち上げることができます。
私の目標は、現在のスループットを維持しながら、最小限の資本でメモリフットプリントを削減し、フォールトトレランスを向上させることです。