【问题标题】:Azure BlobWriteStream The client could not finish the operation within specified timeoutAzure BlobWriteStream 客户端无法在指定的超时时间内完成操作
【发布时间】:2017-11-01 16:53:55
【问题描述】:

我正在尝试将 300GB(流式传输)数据上传到 Azure blob 存储。 我用来执行上传的代码如下所示:

var stream = blob.OpenWrite();
[...]
// the buffer is filled in with 128KB chunks of data from a larger 300GB file
stream.Write(buffer, offset, count);

上传大约 8 小时后,我收到以下错误消息:

在 Microsoft.WindowsAzure.Storage.Core.Util.StorageAsyncResult`1.End() 在 c:\Program 文件中 x86)\Jenkins\workspace\release_dotnet_master\Lib\ClassLibraryCommon\Core\Util\StorageAsyncResult.cs:line 77 在 Microsoft.WindowsAzure.Storage.Blob.BlobWriteStream.EndWrite(IAsyncResult asyncResult) 在 c:\Program Files (x86)\Jenkins\workspace\release_dotnet_master\Lib\ClassLibraryCommon\Blob\BlobWriteStream.cs:line 211

ErrorMessage = 客户端无法在其中完成操作 指定超时。

附带说明,我的上传速度约为 2MB/s(可能与超时消息有关)。任何帮助将不胜感激。

【问题讨论】:

  • 您到底想上传什么?你能把它切成小块吗?你试过多少次了?超过 8 小时的上传尝试超时可能有多种原因。
  • @JuanCarlosEduardoRomainaAc 我正在上传一个简单的 300GB .txt 文件。我正在分块读取文件,然后通过 BlobWriteStream 将每个块发送到 Azure。我尝试了几次,每次都收到相同的超时。

标签: c# azure azure-storage azure-blob-storage


【解决方案1】:

根据您的描述和错误消息,如果您不希望它尽快超时,我建议您可以尝试将BlobRequestOptions.MaximumExecutionTime 的值更改为更长。

我建议您还可以启用存储诊断日志来查看您的存储分析日志和指标,以确定延迟是服务器延迟还是端到端延迟。 有关 Microsoft Azure 存储监控、诊断和故障排除的更多详细信息,您可以参考此article

另外,我建议您可以尝试使用 Microsoft Azure 存储数据移动库将大文件上传到 blob 存储。

这是为高性能上传、下载和复制 Azure 存储 Blob 和文件而设计的。您可以从 VS nuget 包管理器安装它。

更多使用方法,可以参考article

这是一个例子:

 CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
"connectstring");
            CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
            CloudBlobContainer blobContainer = blobClient.GetContainerReference("foobar");
            blobContainer.CreateIfNotExists();
            string sourcePath = @"yourfilepath";
            CloudBlockBlob destBlob = blobContainer.GetBlockBlobReference("foobar");

            TransferManager.Configurations.ParallelOperations = 64;

            SingleTransferContext context = new SingleTransferContext();
            context.ProgressHandler = new Progress<TransferStatus>((progress) =>
            {
                Console.WriteLine("Bytes uploaded: {0}", progress.BytesTransferred);
            });

            var task = TransferManager.UploadAsync(
    sourcePath, destBlob, null, context, CancellationToken.None);
            task.Wait();

它会自动将每个块发送到 Azure 存储,如下所示:

【讨论】:

  • 存储诊断日志已为 blob 启用,我得到的唯一错误是 ClientOtherError(在读取 blob 的属性时发生)。我正在使用您提到的选项重新运行上传,我会及时通知您。
  • 有什么更新吗?如果您觉得我的回答有用/有帮助。请将其标记为答案,以便其他人可以从中受益。
  • 我们已经有了自己的传输流实现,在底层调用 BlobWriteStream。因此,我还无法使用您提到的库,我仍在寻找其他选择。此外,这些测试需要大量时间来重现。不用担心,我会在问题结束后更新问题。
【解决方案2】:

此问题已在 8.1.3 版本中解决(之前我使用的是 8.1.1)。他们的changelogs中也提到了这一变化:

  • Blobs(桌面):修复了一个错误,即不遵守 MaximumExecutionTime 导致无限等待,如果由于失败(例如,在接收到响应标头后出现网络故障),服务器停止发送部分响应。
  • All(Desktop):修复了在重试、取消和表操作期间未释放 SendStream 的内存泄漏问题。

基本上,在 8.1.3 之前,BlobRequestOptions.MaximumExecutionTime 被忽略了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-15
    • 2015-10-03
    • 1970-01-01
    • 2014-11-29
    相关资源
    最近更新 更多