0

範囲ヘッダーを利用して、セグメント化ダウンロードをサポートする http サーバーにファイルをダウンロードしたいとします。例えば:

  • ファイルへの URL: www.music.com/rock.mp3
  • ファイルの長さ: 4000 バイト

2 つのスレッドを起動し、それぞれがファイルの半分のバイトをダウンロードしているとします。

  • スレッド t1 は 0 から 1999 までのバイトをダウンロードします
  • スレッド t2 は 2000 から 3999 までのバイトをダウンロードします

t2 は後半のダウンロードを終了し、t1 はまだバイト 1199 までしかダウンロードしていないため、t1 にはまだバイト 1200 から 1999 が残っており、合計で 800 バイトです。

ここで、t2 にバイト 1600 からバイト 1999 までのダウンロードを開始させ、t1 にバイト 1599 までダウンロードを続けさせます。t2 でこれを行うことに問題はないと思います。範囲が 1600 から 1999 の別の get メッセージを送信するだけで済みます。 t1 は最初に 0 から 1599 ではなく 0 から 1999 の範囲から get メッセージを送信したため、サーバーはバイト 1999 が配信されるまでバイトを t1 に送信し続けます。t1 の観点では、1600 から 1999 までの冗長バイトが含まれます。

  1. t1 の場合、サーバーに「OK プランが変更されました。1599 までしか必要ないので、1599 を送信した時点で停止し、1600 からバイトを送信しないでください」と伝える方法はありますか? 私が思い付くことができる1つの「回避策」は、t1にバイト1600から1999までのバイトを破棄させることですが、これらのバイトはまだ回線経由で配信されているため、帯域幅を消費し、ネットワークスループットに影響を与えます。したい...ダウンロード速度を上げるために動的なセグメント化スキームを設計しようとしているので、ここで速度とスループットに関心があるのはそのためです。おそらく1ギガバイトなどの大きなファイルで、2つのスレッドを使用している場合、最悪の場合、破棄する必要がある冗長バイトはギガバイトの約半分になり、それはたくさんあると思います...繋がり。サーバーが私からの接続終了要求を聞いたとき、サーバーは要求された範囲内の未送信バイト (バイト 1678、1830 など) の送信を即座に停止するのでしょうか --- サーバーが実際に接続終了要求を聞く前に、それを知っています。 、それはまだいくつかの冗長なバイトを送信する可能性があります。ただし、それだけのバイトを破棄することは大きな問題ではありません。

  2. これまでに行ったこと以外に、動的セグメンテーションを機能させる方法はありますか?

  3. 上記のシナリオでは、t2 が 2000 から 3999 までのジョブを終了し、1600 から 1999 までのバイトを取得しようとしている場合、t2 はデフォルトで同じ http 接続を使用して新しい範囲のバイトを取得するか、事前に何かを行う必要があります (たとえば、余分なGET メッセージなどへの引数) を実現するには? そのような場合、同じ接続を使用する方が、別の接続を閉じて開くよりも優れているというのは正しいですか?

私はこれを clojure で書いているので、Java または clojure のコード例があれば非常に役に立ちます。:-)

4

1 に答える 1

0

4M ファイルをダウンロードし、それを 2 つのスレッドで実行したいとします。最初のスレッドが 0 から中央に向かって、2 番目のスレッドが最後から中央に向かってバイトするのはいいことではないでしょうか? これは、この問題を見て最初に頭に浮かんだことです。

範囲を要求できるので、十分な量になったら接続を終了するか、ブロックで作業することができます。4MB のファイルは 1024 ブロックの 4k になります。2 つのスレッドはいずれかの側からブロックを取得し、どちらのスレッドがより多く取得したかを気にせずに、それらの 1024 ブロックを取得したときに停止します。

しかし、これは実際には視覚的に楽しいだけです。n ブロックのカウンター c がある場合、それを使用して、ダウンロードのサイズとスレッドの最大制限に基づいて、多数のスレッドを持つことができます。カウンターをインクリメントし、それをジョブとして保存することで、すべてのユーザーが最初の空きブロックを要求できます。何かが起こった場合は、スレッドのジョブが完了していることを確認する必要があります。それ以外は、カウンターが n に達し、すべてのスレッドが完了したときに完了します。

ビットセットを考えていましたが、各スレッドの現在のジョブとそのカウンターを知ることで十分に制御できると思います。ただし、インクリメントするメソッドが同期されていることを確認してください。

于 2013-08-22T22:31:50.880 に答える