Azure blob的阻止列表为空,但blob不为空!怎么会这样?

时间:2013-02-01 17:52:18

标签: azure azure-storage azure-storage-blobs

简而言之:

可以使用单个PUT请求创建块blob。这将创建一个包含已提交内容的blob,但blob 将不会有任何已提交的块

这意味着您不能假设已提交块的串联与已提交内容相同。

使用块blob时,你必须特别注意带有空块列表的blob,因为这样的blob 可能是也可能不是是空的!


原始问题:

Azure帐户中的一个存储blob有一个空的阻止列表,尽管它不是空的。

我正在检索这样的阻止列表(C#):

foreach (var block in _cloudBlob.DownloadBlockList(
    BlockListingFilter.Committed, 
    AccessCondition.GenerateLeaseCondition(_leaseId)))
{
    // ...
}

foreach块中的代码未执行。返回的列表为空。

但是,当我检查时,blob报告它的长度不为零:_cloudBlob.Properties.Length

我也可以下载blob,看看它不是空的。

我错过了什么吗?当blob不是时,阻止列表如何为空?!

我使用BlockListingFilter.CommittedBlockListingFilter.Uncommitted还是BlockListingFilter.All并不重要;列表仍然是空的!

更新

我已将此blob复制到公共容器中,以便任何人都可以复制此问题。

以下是如何重现我无法理解的内容:

首先使用REST API从Azure获取blob属性:

HEAD http://dfdev.blob.core.windows.net/pub/test HTTP/1.1
Host: dfdev.blob.core.windows.net

响应:

HTTP/1.1 200 OK
Content-Length: 66
Content-Type: application/octet-stream
Last-Modified: Sat, 02 Feb 2013 09:37:19 GMT
ETag: 0x8CFCF40075A5F31
Server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-request-id: 4b149a7e-2fcd-4ab4-8d53-12ef047cbfa1
x-ms-version: 2009-09-19
x-ms-lease-status: unlocked
x-ms-blob-type: BlockBlob
Date: Sat, 02 Feb 2013 09:40:54 GMT

响应标头告诉我们这是一个块blob,它的长度为66个字节。

现在从以下位置检索阻止列表:

http://dfdev.blob.core.windows.net/pub/test?comp=blocklist

回复机构:

<?xml version="1.0" encoding="utf-8"?><BlockList><CommittedBlocks /></BlockList>

因此,blob没有任何已提交的块,但它的长度仍为66字节!

这是一个错误还是我误解了什么?

请帮帮我!

更新2

我发现如果我像这样上传blob:

container.GetBlockBlobReference("put-only")
    .UploadFromStream(File.OpenRead("test-blob"));

...然后将一个PUT请求发送到Azure,并且blob获取一个空的阻止列表(就像上面一样)。

但是,如果我像这样上传blob:

var blob = container.GetBlockBlobReference("put-block");
string blockId = Convert.ToBase64String(Guid.NewGuid().ToByteArray());
blob.PutBlock(blockId, File.OpenRead("test-blob"), null);
blob.PutBlockList(new string[] { blockId });

...然后将两个请求发送到Azure(一个用于放置块,另一个用于放置块列表)。

第二个blob获得一个非空的阻止列表。

为什么单个PUT不会产生阻止列表?

我们难道不能依赖blob提交的块的连接等于blob的实际内容吗?!

如果没有,我们如何确定阻止列表何时正常以及何时不是?

更新3

我为此实现了一种解决方法,我认为在我们遇到此问题的情况下就足够了。如果我们发现一个空的块列表和一个大于零的blob长度,那么我们将假设一切正常(虽然它确实不是)并继续使用Put Block和Put Block List重写该数据。下一个机会。

然而,尽管在我们的例子中这将起作用,但是非空块blob可以有一个空的已提交块列表,这仍然非常令人困惑!!

这是Azure中的副设计吗?谁能解释一下发生了什么?

更新4

Microsoft confirmed this issue on the MSDN forums也是。艾伦·陈引用:

  

我已经与产品团队确认过了。这是正常行为。 x-ms-blob-content-length头是提交的blob的大小。在您的情况下,您使用Put Blob API,因此所有内容都上传到单个API中,并在同一请求中提交。因此,在Get Block List API的响应中,您会看到x-ms-blob-content-length标头的值为66,这意味着提交的blob大小。

     

我们已经意识到Get Block List API的MSDN文档在此方面并不十分明确,并且可以使用它。

1 个答案:

答案 0 :(得分:7)

正如您在测试中发现的那样,查询使用Put Blob上传的块blob的块列表将返回一个空列表。这是设计的。

Storage Client Library中的UploadFromStream API在决定是使用单个Put Blob操作还是一系列Put Block操作后跟Put块列表来上传blob之前进行一些检查。更改此行为的一个属性是SingleBlobUploadThresholdInBytes