批量上载大量图像到Azure Blob存储

时间:2011-10-10 22:25:54

标签: c# azure azure-storage-blobs blobstorage

我有大约110,000张不同格式(jpg,png和gif)和大小(2-40KB)的图像存储在我的硬盘上。我需要将它们上传到Azure Blob存储。在执行此操作时,我需要设置一些元数据和blob的ContentType,否则它是直接批量上传。

我目前正在使用以下内容来处理一次上传一张图片(并行超过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();
    }
}

我想知道是否还有其他技术可以用来处理上传,尽可能快地进行上传。这个特殊的项目涉及将大量数据从一个系统导入另一个系统,以及出于客户原因,它需要尽快发生。

6 个答案:

答案 0 :(得分:7)

好的,这就是我的所作所为。我在一个异步链中运行BeginUploadFromStream(),然后是BeginSetMetadata(),然后是BeginSetProperties(),并行超过5-10个线程(ElvisLive和knightpfhor的建议的组合)。这种方法很有效,但是超过5个线程的表现都非常糟糕,每个线程需要花费20秒钟(一次只能处理10个图像)。

所以,总结性能差异:

  • 异步:5个线程,每个线程运行一个异步链,每个线程一次处理10个图像(出于统计原因分页): ~15.8秒(每个线程)。
  • 同步:1个帖子,一次10张图片(因统计原因分页): ~3.4秒

好的,这很有意思。同步上传blob的一个实例比另一个方法中的每个线程执行好5倍。所以,即使运行5个线程的最佳异步平衡也能实现基本相同的性能

因此,我调整了我的图像文件导入,将图像分成每个包含10,000张图像的文件夹。然后我使用Process.Start()为每个文件夹启动我的blob上传器的实例。我在此批次中有170,000个图像可供使用,因此这意味着上传者的17个实例。在我的笔记本电脑上运行所有这些功能时,所有这些功能的性能均达到 ~4.3秒每套

长话短说,我只是为每10,000张图片运行一个blob上传器实例,而不是试图让线程最佳地工作,而是同时在一台机器上运行。总体性能提升?

  • Async Attempts: 14-16小时,基于运行一两个小时的平均执行时间。
  • 与17个独立实例同步:~1小时,5分钟。

答案 1 :(得分:3)

你绝对应该在多个流中并行上传(即同时发布多个文件),但在你做任何实验(错误地)显示没有好处之前,请确保你实际增加ServicePointManager.DefaultConnectionLimit的值:

  

ServicePoint允许的最大并发连接数   宾语。默认值为2.

默认值为2时,对于任何目标,最多可以有两个未完成的HTTP请求。

答案 2 :(得分:1)

由于您上传的文件非常小,我认为您编写的代码可能与您可以获得的效率相当。根据您的评论,您似乎已经尝试并行运行这些上传,这实际上是我唯一的其他代码建议。

我怀疑为了获得最大的吞吐量,将为您的硬件,连接和文件大小找到合适的线程数。您可以尝试使用Azure Throughput Analyzer来更轻松地找到这种平衡。

微软的Extreme Computing小组也benchmarks and suggestions on improving throughput。它专注于部署在Azure上的工作者角色的吞吐量,但它会让您了解您希望的最佳效果。

答案 3 :(得分:1)

您可能希望增加ParallelOperationThreadCount,如下所示。我没有检查最新的SDK,但在1.3中限制为64.未设置此值会导致较低的并发操作。

CloudBlobClient blobStorage = new CloudBlobClient(config.AccountUrl, creds);
// todo: set this in blob extensions
blobStorage.ParallelOperationThreadCount = 64

答案 4 :(得分:1)

如果并行方法上传的内容比串行方法多5倍,那么你要么

  • 带来可怕的带宽
  • 计算机速度很慢
  • 做错了什么

我的命令行util在并行运行时获得了相当大的提升,即使我不使用内存流也没有任何其他漂亮的东西,我只是生成文件名的字符串数组,然后用{{1上传它们}}

此外,Parallel.ForEach调用可能会让您回头相当多。我个人从不使用它们,我想它们甚至不应该重要,除非你想通过直接的URL在浏览器中查看它们。

答案 5 :(得分:0)

您可以随时尝试上传的异步方法。

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

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