【问题标题】:Azure Page Blob OpenRead does not fetch more than StreamMinimumReadSizeInBytesAzure Page Blob OpenRead 获取的数据不超过 StreamMinimumReadSizeInBytes
【发布时间】:2017-04-03 16:55:24
【问题描述】:

我有一个包含有效日志数据的页面 blob。在日志填满 2 MB 之前一切正常。

在阅读时,我使用 OpenReadAsync 方法来获取我从中读取数据的流。在调用 OpenReadAsync 之前,我将 StreamMinimumReadSizeInBytes 设置为 2MB (2 * 1024 * 1024)。

打开流后,我使用以下方法读取数据。

public IEnumerable<object> Read(Stream pageAlignedEventStream, long? maxBytes = null)
    {
        while (pageAlignedEventStream.Position < (maxBytes ?? pageAlignedEventStream.Length))
        {
            byte[] bytesToReadBuffer = new byte[LongZero.Length];
            pageAlignedEventStream.Read(bytesToReadBuffer, 0, LongZero.Length);
            long bytesToRead = BitConverter.ToInt64(bytesToReadBuffer, 0);

            if (bytesToRead == 0)
            {
                yield break;
            }

            if (bytesToRead < 0)
            {
                throw new InvalidOperationException("Invalid size specification.  Stream may be corrupted.");
            }

            if (bytesToRead > Int32.MaxValue)
            {
                throw new InvalidOperationException("Payload size is too large.");
            }

            byte[] payload = new byte[bytesToRead];                
            int read = pageAlignedEventStream.Read(payload, 0, (int) bytesToRead);

            if (read != bytesToRead)
            {
                // when fails, read == 503, bytesToRead = 3575, position = 2MB (2*1024*14024)
                throw new InvalidOperationException("Did not read expected number of bytes.");
            }

            yield return this.EventSerializer.DeserializeFromStream(new MemoryStream(payload, false));

            var paddedSpaceToSkip = PagesRequired(bytesToRead) * PageSizeBytes - bytesToRead - LongZero.Length;
            pageAlignedEventStream.Position += paddedSpaceToSkip;
        }

        yield break;
    } 

如代码中的 cmets 所述,失败发生在位置达到指定的 2MB 时。读取无法在返回之前提取额外的字节,并且仅读取 503 个字节而不是预期的 3575 个字节。

我的期望是,当我读取超过缓冲区大小时,它会下载更多数据。

我在 Azure Feedback 上发现了类似的问题,但链接的问题表明缓冲区大小不是 2 的幂,但 2MB 绝对是 2 的幂。

【问题讨论】:

    标签: azure-blob-storage


    【解决方案1】:

    即使我将 CloudPageBlob 的 StreamMinimumReadSizeInBytes property 设置为 2MB,我也可以获取存储在页面 blob 中的所有数据(大小 = 3MB)。

    CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
                        CloudConfigurationManager.GetSetting("StorageConnectionString"));
    
    CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
    
    CloudBlobContainer container = blobClient.GetContainerReference("mycontainername");
    
    container.CreateIfNotExists();
    
    CloudPageBlob pageBlob = container.GetPageBlobReference("mypageblob");
    
    pageBlob.StreamMinimumReadSizeInBytes = 2 * 1024 * 1024;
    
    Task<Stream> pageAlignedEventStream = pageBlob.OpenReadAsync();
    

    读取在返回之前未能提取额外的字节,仅读取 503 个字节而不是预期的 3575 个字节。

    如果当前没有那么多字节可用并且已到达流的末尾,则返回值可能小于请求的字节数。请调试您的代码,跟踪paddedSpaceToSkip变量的变化,检查您的代码逻辑是否符合预期。

    【讨论】:

    • 代码运行正常。我编写了自己的流实现,它可以从 blob 中读取块并使用该流,一切都很好。使用 OpenReadAsync 流对我不起作用。我想知道产量是否会导致问题,因为我没有一次读取所有字节?
    • 此外,由于所有对象的大小都相同,并且它们读取良好,因此读取不是问题。它仅在 2MB 边界处。该对象存在于边界上。 read 调用返回的字节数少于预期,而在 2MB 缓冲区之后还有更多可用的字节数。
    • 你能分享一下你用来获取 pageAlignedEventStream 的代码吗?
    猜你喜欢
    • 2016-04-16
    • 1970-01-01
    • 2021-06-22
    • 1970-01-01
    • 2022-08-05
    • 2019-12-16
    • 2021-08-16
    • 2020-09-03
    • 1970-01-01
    相关资源
    最近更新 更多