私は、あるサーバーから別のサーバーに非常に大きなストリーミング データ セット (おそらく単一ストリームで数テラバイト、通常は数十ギガバイト) を転送するツールを構築しています。ツールのクライアント部分は、ソース ディスクからブロックを読み取り、ネットワーク経由で送信します。サーバー側はこれらのブロックをネットワークから読み取り、サーバー ディスク上のファイルに書き込みます。
現在、どの交通機関を利用するか検討中です。オプションは raw TCP と HTTP です。
私は本当に、本当にHTTPを使用できるようにしたいと思っています。HttpListener (または、そのルートに行きたい場合は WCF) を使用すると、HTTP サーバー API (http.sys) に簡単にプラグインでき、認証や SSL などを無料で取得できます。今の問題はパフォーマンスです。
サーバー側で async BeginRead/EndRead を使用して、BeginWrite/EndWrite 非同期 I/O イディオムを使用して 128K ブロックの NULL バイトを送信する簡単なテスト ハーネスを作成しました。HttpWebRequest
このテスト ハーネスを変更して、 /を介した HTTP PUT 操作、または/HttpListener
を使用した単純な古いソケット書き込みのいずれかでこれを実行できるようにしました。ネットワーク カードまたはネットワーク パスの問題を除外するために、クライアントとサーバーの両方が 1 台のマシン上にあり、localhost 経由で通信します。TcpClient
TcpListener
私の 12 コア Windows 2008 R2 テスト サーバーでは、このテスト ハーネスの TCP バージョンは、最小の CPU 使用率で 450MB/秒でバイトをプッシュできます。同じボックスで、テスト ハーネスの HTTP バージョンは、調整方法に応じて 130MB/s から 200MB/s の間で実行されます。
どちらの場合も CPU 使用率は低く、CPU 使用率の大部分はカーネル時間であるため、C# と .NET ランタイムの使用がボトルネックではないと確信しています。このボックスには、2 つの 6 コア Xeon X5650 プロセッサ、24 GB のシングルランク DDR3 RAM が搭載されており、私自身のパフォーマンス テスト専用に使用されています。
、、、、などServicePointManager.MaxServicePointIdleTime
のHTTP クライアントの微調整については既に知っています。 ServicePointManager.DefaultConnectionLimit
ServicePointManager.Expect100Continue
HttpWebRequest.AllowWriteStreamBuffering
HTTP.sys のパフォーマンスを 200MB/s を超えるようにする方法について、誰かアイデアはありますか? どの環境でもこれほどうまく機能するのを見た人はいますか?
更新:
TcpListener
vsで見たパフォーマンスの詳細を次に示しますHttpListener
。
まず、TcpClient/TcpListener テストを作成しました。私のテストボックスでは、450MB/s をプッシュできました。
次に、リフレクターを使用して、HttpWebRequest の基になる未加工の Socket オブジェクトを取得する方法を見つけ、それを使用するように HTTP クライアント テストを変更しました。まだ喜びはありません。かろうじて200MB/秒。
私の現在の理論では、http.sys は典型的な IIS のユース ケースに合わせて最適化されているというものです。これは、多数の同時実行の小さな要求と、多数の同時実行の、場合によっては大規模な応答です。この最適化を達成するために、MSFT は私が達成しようとしていることを犠牲にしてそうしなければならなかったと仮定します。これは、単一の非常に大きな要求で非常に高いスループットを実現し、応答は非常に小さくなります。
価値のあるものとして、最大 32 の同時 HTTP PUT 操作も試して、スケールアウトできるかどうかを確認しましたが、それでも満足できるものではありませんでした。約200MB/秒。
興味深いことに、64 ビット Windows 7 を実行するクアッドコア Xeon Precision T7400 である私の開発ワークステーションでは、私の TcpClient 実装は約 200MB/秒であり、HTTP バージョンも約 200MB/秒です。Server 2008 R2 を実行しているハイエンドのサーバークラスのマシンにそれを持っていくと、TcpClient コードは最大 450MB/秒になり、HTTP.sys コードは約 200 のままです。
残念ながら、この時点で、HTTP.sys は私が必要とする仕事に適したツールではなく、ずっと使用してきた手巻きのソケット プロトコルを引き続き使用する必要があるという結論に達しました。