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

本文关键字:Azure Blob 存储 图像 | 更新日期: 2023-09-27 18:10:49

我的硬盘上本地存储了大约110000张各种格式(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();
    }
}

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

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

好的,这是我所做的。我修改了在异步链中运行BeginUploadFromStream((、BeginSetMetadata((和BeginSetProperties((,并行5-10个线程(ElvisLive和knightpfhor建议的组合(。这是有效的,但任何超过5个线程的线程都有糟糕的性能,每个线程(一次处理10个图像的页面(需要20秒以上的时间才能完成。

因此,总结性能差异:

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

好吧,这很有趣。一个实例同步上传Blob的性能是另一种方法中每个线程的5倍。因此,即使运行5个线程的最佳异步平衡,网络的性能也基本相同

因此,我调整了我的图像文件导入,将图像分离到每个包含10000个图像的文件夹中。然后,我使用Process.Start((为每个文件夹启动一个blob上传程序实例。我在这个批次中有170000个图像要处理,所以这意味着上传器有17个实例。当在我的笔记本电脑上运行所有这些程序时,所有程序的性能都稳定在~4.3秒/套

长话短说,我没有试图让线程以最佳方式工作,而是为每10000个图像运行一个blob上传器实例,所有这些都同时在一台机器上。整体性能提升?

  • 异步尝试次数:14-16小时,基于运行一到两小时的平均执行时间
  • 与17个独立实例同步:约1小时5分钟

您肯定应该在多个流中并行上传(即同时发布多个文件(,但在进行任何实验(错误地(表明没有好处之前,请确保您确实增加了ServicePointManager.DefaultConnectionLimit:的值

ServicePoint允许的最大并发连接数对象默认值为2。

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

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

我怀疑,为了获得最大的吞吐量,需要为您的硬件、连接和文件大小找到合适数量的线程。你可以尝试使用Azure吞吐量分析器来更容易地找到这种平衡。

微软的极限计算小组也提出了提高吞吐量的基准和建议。它专注于部署在Azure上的工作人员角色的吞吐量,但它会让你知道你所希望的最好结果。

您可能需要增加ParallelOperationThreadCount,如下所示。我还没有查看最新的SDK,但在1.3中,限制是64。不设置此值会导致并发操作减少。

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

如果并行方法的上传时间是串行方法的5倍,那么您

  • 有糟糕的带宽
  • 有一台很慢的电脑
  • 做错事

当并行运行时,我的命令行实用程序得到了很大的提升,尽管我既不使用内存流,也不使用任何其他类似的漂亮东西,我只是生成一个文件名的字符串数组,然后用Parallel.ForEach上传它们。

此外,Properties.ContentType调用可能会让您倒退很多。就我个人而言,我从来没有使用过它们,我想它们甚至都不重要,除非你想通过直接的URL在浏览器中查看它们。

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

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

)

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