当前位置: 首页 > 编程语言 > C#

为什么上传到Azureblob这么慢?分享

时间:2023-04-10 20:47:26 C#

为什么上传到Azureblob这么慢?我有一个自定义流,用于直接在页面云blob中写入。publicsealedclassWindowsAzureCloudPageBlobStream:Stream{//4MB是页面blob写入操作的最高限制publicconstintMaxPageWriteCapacity=4*1024*1024;//页面blob上的每个操作都必须操作一个四舍五入到512字节的值privateconstintPageBlobPageAdjustmentSize=512;私有CloudPageBlob_pageBlob;publicoverridevoidWrite(byte[]buffer,intoffset,intcount){varadditionalOffset=0;varbytesToWriteTotal=计数;列表列表=新列表();while(bytesToWriteTotal>0){varbytesToWriteTotalAdjusted=RoundUpToPageBlobSize(bytesToWriteTotal);//Azure不允许我们写入任意数量的字节//每次写入的最大允许大小为4MBvarbytesToWriteNow=Math.Min((int)bytesToWriteTotalAdjusted,MaxPageWriteCapacity);varadjustmentBuffer=newbyte[bytesToWriteNow];...varmemoryStream=newMemoryStream(adjustmentBuffer,0,bytesToWriteNow,false,false);var任务=_pageBlob.WritePagesAsync(memoryStream,Position,null);列表。添加(任务);}Task.WaitAll(list.ToArray());}privatestaticlongRoundUpToPageBlobSize(longsize){return(size+PageBlobPageAdjustmentSize-1)&~(PageBlobPageAdjustmentSize-1);我的Write()性能很低,例如:Stopwatchs=newStopwatch();s.开始();使用(varmemoryStream=newMemoryStream(adjustmentBuffer,0,bytesToWriteNow,false,false)){_pageBlob.WritePages(memoryStream,Position);}s.Stop();Console.WriteLine(s.Elapsed);=>00:00:01.52==平均速度2.4MB/s如何改进我的算法?如何使用Parallel.ForEach加快进程?为什么只有2.5MB/秒,而不是像官方网站或http://blogs.microsoft.co.il/applisec/2012/01/05/windows-azure-benchmarks-part-2-blob那样的60MB/秒-writeflux/像你一样,我有很多页面blob的性能问题——即使它们没有那么严重。看起来你已经完成了功课,我可以看到你正在做书中的所有事情。要检查的一些事项:还有一件事:访问时间慢的主要原因是因为您同步执行所有操作。Microsoft的基准测试可以在多个线程中访问blob,这将提供更高的吞吐量。现在,Azure也知道性能是一个问题,这就是为什么他们试图通过本地缓存后备存储来缓解这一问题。基本上这里发生的是他们在本地写入数据(例如在文件中),然后将任务分成碎片,然后使用多个线程将所有内容写入blob存储。DatastoreMotion库就是这样一种库。但是,在使用它们时,您应该始终牢记它们具有不同的持久性约束(例如在本地PC上启用“写入缓存”)并且可能会破坏您设置分布式系统的方式(如果您读取和写入相同的导入内容)来自多个VM的存储)。为什么……你问的是“为什么”。为了理解为什么blob存储速度慢,您需要了解它是如何工作的。首先,我想指出MicrosoftAzure的这个演示文稿,它解释了Azure存储的实际工作原理。您应该意识到的第一件事是Azure存储由一组分布式(旋转)磁盘支持。由于持久性和一致性限制,他们还确保将数据写入稳定存储的“多数票”。为了性能,系统的多个级别都会有缓存,主要是读取缓存(同样,由于持久性约束)。现在,Azure团队并没有发布所有内容。幸运的是,我之前的公司在5年前创建了一个规模较小的类似系统。我们在一个与我上面链接的演示文稿非常相似的系统中遇到了类似Azure的性能问题。所以我想我可以解释和推测瓶颈在哪里。为清楚起见,我将在我认为合适的情况下将章节标记为推测性的。如果将页面写入blob存储,实际上是建立了一系列TCP/IP连接,将页面存储在多个位置,当收到多数票时,您将向客户端返回“ok”。现在,这个系统实际上有一些瓶颈:你必须在整个基础设施上建立一堆TCP/IP连接。设置这些需要时间。存储的端点必须执行磁盘搜索到正确的位置并执行操作。异地复制当然比本地复制需要更多时间。【推测】我们还发现很多时间花在了“缓冲”阶段。这里数字(1)、(2)和(3)是众所周知的。这里的数字(4)实际上是(1)和(2)的结果。请注意,您不能只向旋转的磁盘发出无限数量的请求;好吧......实际上你可以,但系统将逐渐停止。因此,为了解决这个问题,来自不同客户端的磁盘搜索通常以这样一种方式安排,只要您也知道,您就可以自己编写所有内容(以最大限度地减少昂贵的搜索)。然而,这里有一个陷阱:如果你想提高吞吐量,你需要在你拥有所有数据之前开始寻找——如果你获取数据的速度不够快,其他请求就不得不等待更长的时间。这也是一个两难选择:您可以为此进行优化(这有时会损害每个客户端的吞吐量并阻塞其他所有人,尤其是在混合工作负载的情况下)或缓冲所有内容然后立即查找和写入所有内容(这更容易,但会为每个人增加一些延迟).由于Azure提供了大量的客户端,我怀疑他们选择了最后一种方法——这增加了整个写入周期的延迟。不过,大部分时间可能会花在(1)和(2)上。实际的数据突发和数据写入都非常快。给你一个粗略的估计:这里有一些常用的时间。所以,这给我们留下了一个问题:为什么在多线程中写入要快得多?这样做的原因实际上很简单:如果我们在多线程中编写内容,我们很有可能将实际数据存储在不同的服务器上。这意味着我们可以将瓶颈从“搜索+网络设置延迟”转移到“吞吐量”。只要我们的客户端VM可以处理它,基础架构也很可能能够处理它。如果您不介意处理文件而不是流(或者这可能支持流但我不知道),请查看Azure存储数据移动库。这是迄今为止我见过的最好的。它相对较新(在撰写本文时),但对以块的形式移动大文件和最大化吞吐量有很好的支持(我用它来每晚复制SQL备份,其中许多超过1GB)。https://azure.microsoft.com/en-us/blog/announcing-azure-storage-data-movement-library-0-2-0/用法很简单。这是一个例子:usingMicrosoft.WindowsAzure.Storage;使用Microsoft.WindowsAzure.Storage.Blob;使用Microsoft.WindowsAzure.Storage.DataMovement;namespaceBlobUploader{publicclassUploader{publicstringConnectionString{get;放;}publicstringContainerName{get;放;}公共字符串BlobName{得到;放;}publicvoidUploadFile(stringfilePath){CloudStorageAccountaccount=CloudStorageAccount.Parse(ConnectionString);CloudBlobClientblobClient=account.CreateCloudBlobClient();CloudBlobContainerblobContainer=blobClient.GetContainerReference(ContainerName);blobContainer.CreateIfNotExists();CloudBlockBlobdestinationBlob=blobContainer.GetBlockBlobReference(BlobName);TransferManager.Configurations.ParallelOperations=64;TransferContextcontext=newTransferContext();context.ProgressHandler=newProgress((progress)=>{Console.WriteLine("上传的字节数:{0}",progress.BytesTransferred);});vartask=TransferManager.UploadA同步(文件路径,destinationBlob,空,上下文,CancellationToken.None);任务.等待();下面的预览博客文章提供了一些关于它是如何产生的以及它如何处理一般事情的信息:https://azure.microsoft.com/en-us/blog/introducing-azure-storage-data-movement-library-preview-2/...一种快速简便的检查方法:确保您的blob存储位于您的VM或应用程序正在运行的同一Azure区域中遇到的一个问题是我们的存储帐户位于另一个区域我们的应用程序。这导致我们在处理过程中出现严重延误。我们一直在摸不着头脑,直到我们意识到我们正在跨区域读写。菜鸟的错误都是我们的错!以上是C#学习教程:为什么上传到Azureblob这么慢?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: