Azure blob的阻止列表为空,但blob不为空!怎么会这样? [英] Azure blob's block list is empty, but blob is not empty! How can this be?

查看:96
本文介绍了Azure blob的阻止列表为空,但blob不为空!怎么会这样?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题简而言之:

可以使用单个PUT请求创建块Blob.这将创建一个包含已提交内容的Blob,但该Blob 将没有任何已提交的块

A block blob can be created with a single PUT request. This will create a blob with committed content but the blob will not have any committed blocks!

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

This means that you cannot assume that the concatenation of committed blocks is the same as the committed content.

在使用块Blob时,您必须特别注意块列表为空的Blob,因为这些Bem 可能为空为空!

When working with block blobs you'll have to pay extra attention to blobs with empty block lists, because such blobs may or may not be empty!

原始问题:

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

One of our storage blobs in an Azure account has an empty block list, although it is non-empty.

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

I'm retrieving the block list like this (C#):

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

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

The code in the foreach block is NOT executed. The returned list is empty.

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

However, the blob reports that it has a non-zero length when I check: _cloudBlob.Properties.Length

我还可以下载该blob,然后查看它是否为空.

I can also download the blob and see that it is not empty.

我错过了什么吗?如果Blob不存在,如何阻止列表为空?!

Am I missing something? How can the block list be empty when the blob is not?!

我是否使用 BlockListingFilter.Committed BlockListingFilter.Uncommitted BlockListingFilter.All 都没有关系;列表仍然是空的!

It does not matter whether I use BlockListingFilter.Committed, BlockListingFilter.Uncommitted or BlockListingFilter.All; the list is still empty!

更新

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

I have copied this blob to a public container so that this issue can be reproduced by anyone.

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

Here's how to reproduce what I'm unable to understand:

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

First get blob properties from Azure using the REST API:

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个字节.

The response headers tell us that this is a block blob and that it has a length of 66 bytes.

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

Now retrieve the block list from:

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

响应正文:

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

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

So, the blob does not have any committed blocks, still it has a length of 66 bytes!

这是错误还是我误解了?

Is this a bug or have I misunderstood something?

请帮帮我!

更新2

我发现,如果我这样上传Blob:

I've found that if I upload the blob like this:

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

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

...then a single PUT request is sent to Azure and the blob gets an empty block list (just like above).

但是,如果我这样上传Blob:

However, if I upload the blob like this:

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(一个用于放置阻止,另一个用于放置阻止列表).

...then two requests are sent to Azure (one for putting the block and another for putting the block list).

第二个Blob获得一个非空的阻止列表.

The second blob gets a non-empty block list.

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

Why won't a single PUT yield a block list?

我们不能依靠blob的已提交块的串联等于blob的实际内容吗?!

Can't we rely on that the concatenation of a blob's committed blocks are equal to the blob's actual content?!

如果没有,我们将如何确定阻止列表何时可以正常运行?何时不可以?

If not, how shall we determine when the block list is OK and when it's not??

更新3

我已经实现了一个变通办法,在我们遇到此问题的情况下,我认为就足够了.万一我们发现一个空的阻止列表并且blob长度大于零,那么我们将假定一切都很好(尽管实际上不是),然后继续使用Put Block和Put Block List重写该数据.下一个机会.

I've implemented a workaround for this that I think suffice in the case where we encountered this problem. In case we discover an empty block list AND a blob length that is greater than zero, then we'll assume that everything is OK (although it really isn't) and go ahead and rewrite that data using Put Block and Put Block List at the next opportunity.

但是,尽管在我们的例子中这可以解决问题,但非空块Blob可以包含一个空的已提交块列表,仍然令人非常困惑!

However, although this will do the trick in our case, it is still very confusing that a non-empty block blob can have an empty list of committed blocks!!

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

Is this by-design in Azure? Can anyone explain what's going on?

更新4

Microsoft 确认了此问题在MSDN论坛上.来自艾伦·陈(Allen Chen)的引用:

Microsoft confirmed this issue on the MSDN forums too. Quote from Allen Chen:

我已与产品团队确认.这是正常现象.x-ms-blob-content-length标头是提交的Blob的大小.在您的情况下,您可以使用Put Blob API,以便将所有内容上传到单个API中,并在同一请求中提交.结果,在获取阻止列表" API的响应中,您看到x-ms-blob-content-length标头的值为66,这意味着已提交的blob大小.

I've confirmed with the product team. This is a normal behavior. The x-ms-blob-content-length header is the size of the committed blob. In your case you use Put Blob API so all content is uploaded in a single API and is committed in the same request. As a result in the Get Block List API's response you see the x-ms-blob-content-length header has value of 66 which means the committed blob size.

我们已经知道,获取阻止列表API的MSDN文档对此尚不十分清楚,并且可以在此问题上解决.

We have been aware of the issue that the MSDN document of the Get Block List API is not quite clear on this and will work on it.

推荐答案

正如您在测试中一样,查询使用

As you also identified with your tests, querying the list of blocks of a block blob uploaded using Put Blob will return an empty list. This is by design.

UploadFromStream API进行了几次检查.更改此行为的一个属性是 SingleBlobUploadThresholdInBytes

UploadFromStream API in the Storage Client Library makes a couple of checks before deciding whether to upload a blob using a single Put Blob operation or a sequence of Put Block operations followed by a Put Block List. One property that changes this behavior is SingleBlobUploadThresholdInBytes.

这篇关于Azure blob的阻止列表为空,但blob不为空!怎么会这样?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆