10

この問題を一言で言えば:

ブロック BLOB は、1 つの PUT 要求で作成できます。これにより、コミットされたコンテンツを含む BLOB が作成されますが、BLOBにはコミットされたブロックがありません

これは、コミットされたブロックの連結がコミットされたコンテンツと同じであると想定できないことを意味します。

ブロック BLOB を操作するときは、ブロック リストが空の BLOB に特に注意する必要があります。


元の質問:

Azure アカウントのストレージ BLOB の 1 つに、空ではないものの、空のブロック リストがあります。

次のようにブロック リストを取得しています (C#):

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

foreachブロック内のコードは実行されません。返されたリストは空です。

ただし、チェックすると、ブロブの長さがゼロではないことが報告されます。_cloudBlob.Properties.Length

また、ブロブをダウンロードして、空ではないことを確認することもできます。

何か不足していますか?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>

したがって、ブロブにはコミットされたブロックがありませんが、それでも長さは 66 バイトです!

これはバグですか、それとも何か誤解していますか?

私を助けてください!

更新 2

次のようにブロブをアップロードすると、次のことがわかりました。

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

...次に、単一の PUT 要求が Azure に送信され、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 });

...次に、2 つの要求が Azure に送信されます (1 つはブロックを配置するため、もう 1 つはブロック リストを配置するため)。

2 番目の BLOB は、空でないブロック リストを取得します。

単一の PUT でブロック リストが得られないのはなぜですか?

BLOB のコミットされたブロックの連結が BLOB の実際のコンテンツと等しいとは言えませんか?!

そうでない場合、ブロックリストがOKである場合とそうでない場合をどのように判断しますか??

更新 3

この問題が発生した場合には、これで十分だと思われる回避策を実装しました。空のブロック リストと 0 より大きい BLOB の長さを検出した場合は、すべて問題ないと見なし (実際にはそうではありません)、先に進み、Put Block と Put Block List at を使用してそのデータを書き換えます。次の機会。

ただし、これで問題は解決しますが、空でないブロック BLOB がコミットされたブロックの空のリストを持つ可能性があることは、依然として非常に混乱を招きます!!

これは Azure の設計によるものですか? 誰が何が起こっているのか説明できますか?

更新 4

Microsoftは、MSDN フォーラムでもこの問題を確認しています。アレン・チェンからの引用:

製品チームに確認済みです。これは正常な動作です。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 ドキュメントでは、これについて明確ではなく、今後も対応する予定であるという問題を認識しています。

4

1 に答える 1

9

テストで確認したように、 Put Blobを使用してアップロードされたブロック BLOB のブロックのリストをクエリすると、空のリストが返されます。これは仕様によるものです。

Storage Client Library の UploadFromStream API は、Blob をアップロードする前に、単一の Put Blob 操作を使用するか、一連の Put Block 操作とその後に Put Block List を使用するかを決定する前に、いくつかのチェックを行います。この動作を変更する 1 つのプロパティは、SingleBlobUploadThresholdInBytesです。

于 2013-02-04T22:21:16.967 に答える