10

さまざまな形式 (jpg、png、gif) とサイズ (2 ~ 40 KB) の約 110,000 枚の画像がハード ドライブにローカルに保存されています。それらを Azure Blob Storage にアップロードする必要があります。これを行っている間、いくつかのメタデータと BLOB の ContentType を設定する必要がありますが、それ以外はそのまま一括アップロードになります。

私は現在、一度に 1 つの画像のアップロードを処理するために次を使用しています (5 ~ 10 の同時タスクで並列処理)。

static void UploadPhoto(Image pic, string filename, ImageFormat format)
{
    //convert image to bytes
    using(MemoryStream ms = new MemoryStream())
    {
        pic.Save(ms, format);
        ms.Position = 0;

        //create the blob, set metadata and properties
        var blob = container.GetBlobReference(filename);
        blob.Metadata["Filename"] = filename;
        blob.Properties.ContentType = MimeHandler.GetContentType(Path.GetExtension(filename));

        //upload!
        blob.UploadFromStream(ms);
        blob.SetMetadata();
        blob.SetProperties();
    }
}

アップロードをできるだけ速く処理するために採用できる別の手法があるかどうか疑問に思っていました。この特定のプロジェクトでは、あるシステムから別のシステムに大量のデータをインポートする必要があり、顧客の理由により、できるだけ迅速に行う必要があります。

4

6 に答える 6

7

さて、これが私がしたことです。私は、BeginUploadFromStream()、BeginSetMetadata()、BeginSetProperties() を非同期チェーンで実行し、5 ~ 10 スレッド (ElvisLive と Knightpfhor の提案の組み合わせ) で並列処理を実行してみました。これは機能しましたが、スレッドが 5 つを超えるとパフォーマンスが低下し、各スレッド (一度に 10 枚の画像のページを処理) が完了するまでに 20 秒以上かかりました。

したがって、パフォーマンスの違いをまとめると、次のようになります。

  • 非同期: 5 つのスレッド、それぞれが非同期チェーンを実行し、それぞれが一度に 10 個の画像を処理します (統計上の理由からページ化されます): ~15.8 秒 (スレッドあたり)。
  • 同期: 1 スレッド、一度に 10 枚の画像 (統計上の理由からページング): ~3.4 秒

わかりました、それはかなり興味深いです。BLOB を同期的にアップロードする 1 つのインスタンスは、他のアプローチの各スレッドよりも 5 倍優れたパフォーマンスを発揮しました。そのため、5 つのスレッドを最適な非同期バランスで実行しても、基本的に同じパフォーマンスが得られます。

そこで、画像ファイルのインポートを微調整して、画像をそれぞれ 10,000 個の画像を含むフォルダーに分けました。次に、Process.Start() を使用して、フォルダーごとにブロブ アップローダーのインスタンスを起動しました。このバッチで処理する画像が 170,000 あるので、アップローダのインスタンスは 17 になります。これらすべてをラップトップで実行すると、すべてのパフォーマンスが1 セットあたり約 4.3 秒で横ばいになりました。

簡単に言えば、スレッド化を最適に機能させる代わりに、10,000 枚の画像ごとにブロブ アップローダー インスタンスを実行するだけで、すべてを 1 台のマシンで同時に実行できます。全体的なパフォーマンスの向上?

  • Async Attempts: 14 ~ 16 時間(1 ~ 2 時間実行した場合の平均実行時間に基づく)。
  • 17 の個別のインスタンスと同期: ~1 時間 5 分。
于 2011-10-12T00:26:42.090 に答える
3

間違いなく複数のストリームで並行してアップロードする (つまり、複数のファイルを同時に投稿する) 必要がありますが、(誤って) メリットがないことを示す実験を行う前に、実際に の値を増やしてくださいServicePointManager.DefaultConnectionLimit:

ServicePoint オブジェクトによって許可される同時接続の最大数。デフォルト値は 2 です。

デフォルト値の 2 では、任意の宛先に対して最大 2 つの未処理の HTTP 要求を持つことができます。

于 2011-10-12T00:37:24.840 に答える
1

パラレル方式がシリアル方式よりもアップロードに 5 倍の時間がかかる場合は、次のいずれかを行います。

  • 帯域幅がひどい
  • 非常に遅いコンピューターを持っている
  • 何か間違ったことをする

私のコマンドラインユーティリティは、メモリストリームやその他の気の利いたものを使用していなくても、並行して実行するとかなり向上します.ファイル名の文字列配列を生成し、Parallel.ForEach.

さらに、Properties.ContentType電話はおそらくあなたをかなり後退させます。個人的にはそれらを使用したことはありませんし、直接 URL を介してブラウザーで直接表示したい場合を除き、それらは重要ではないと思います。

于 2014-02-01T13:01:18.490 に答える
1

あなたがアップロードしているファイルはかなり小さいので、あなたが書いたコードはおそらく可能な限り効率的だと思います。あなたのコメントに基づいて、これらのアップロードを並行して実行しようとしたようです。これは、私が持っていた唯一の他のコードの提案でした。

最大のスループットを得るには、ハードウェア、接続、およびファイル サイズに適したスレッド数を見つけることが重要だと思います。Azure スループット アナライザーを使用して、このバランスを簡単に見つけることができます。

Microsoft の Extreme Computing グループも、スループットの向上に関するベンチマークと提案を行っています。Azure にデプロイされたワーカー ロールからのスループットに焦点を当てていますが、期待できる最高のアイデアが得られます。

于 2011-10-11T21:03:22.503 に答える
1

以下に示すように、ParallelOperationThreadCount を増やすことができます。最新の SDK は確認していませんが、1.3 では制限が 64 でした。この値を設定しないと、同時操作が少なくなります。

CloudBlobClient blobStorage = new CloudBlobClient(config.AccountUrl, creds);
// todo: set this in blob extensions
blobStorage.ParallelOperationThreadCount = 64
于 2011-10-12T21:39:11.553 に答える
0

アップロードの非同期メソッドをいつでも試すことができます。

public override IAsyncResult BeginUploadFromStream (
Stream source,
AsyncCallback callback,
Object state

)

http://msdn.microsoft.com/en-us/library/windowsazure/ee772907.aspx

于 2011-10-11T05:25:21.240 に答える