Azure blob 存储 - 以错误的顺序获取块列表 returns 未提交的块
Azure blob storage - Get Block List returns uncommitted blocks in the wrong order
我有一个批量上传系统,我想执行以下操作:
- 将一大块数据上传到服务器,服务器会将其作为块 blob 上的未提交块。
- 上传者对 block/blob 实现一无所知。它只知道它正在存储一大块数据。
- 服务器也无法在调用之间保留任何状态。
- 一旦所有块都已上传(上传者在最后一个块上设置标志),服务器将:
- 获取 blob 上未提交块的列表(请记住,它无法保留状态,因此无法将此列表保存在内存中)然后
- 调用以提交它们 (PutBlockList)。 它们必须按正确的顺序提交。
但是从 API 返回的块的顺序不是文档所说的顺序。
根据 Azure 存储 API 站点,
The list of uncommitted blocks is returned beginning with the most recently uploaded block to the oldest uploaded block.
(https://msdn.microsoft.com/en-us/library/azure/dd179400.aspx , under the Remarks section at the bottom)
但是,原始 API 调用和 Microsoft Azure 存储 SDK 都按字母顺序返回块,而不是按它们以任何方式上传的顺序。
我是不是看错了文档?这可能是 API 中的错误吗?本地存储模拟器也给出了相同的结果。
谢谢!
我们检查了存储服务端的内容,结果是:文档有一个错误。从第 1 天开始,未提交块列表按字母顺序返回。我们将尽快更新 MSDN 文档以消除错误,对于给您带来的不便,我们深表歉意!
这里有一些解决问题的方法:
- 如果您无法在本地保存任何状态,请尝试与您的 put 块调用并行将块 ID 存储在云中。我建议使用 append blob 来存储这些。
探索其他一些 blob 类型。
如果您想按上传顺序写入数据,附加 blob 总体上可能更好。追加 blob 具有与块 blob 相同的读取行为和吞吐量,但不允许您更新或删除已经放置的块。但是,要附加数据,您需要做的就是一个 appendBlock ,这将添加到 blob 的末尾——不需要提交!
页 blob 还允许您在不提交的情况下放置数据。与附加 blob 不同,它们将允许在 blob 的中间进行修改。但是,它们对可被 512 整除的数据长度有严格限制。因此,如果这不是您数据的自然 属性,则您需要处理填充。
SDK 对附加和页面有很好的分块支持,您只需将数据放入其中,数据就会被放入。对于块当然也有分块,但状态是在客户端维护的。
- 按照字母顺序排列 属性 并使您的块 ID 按字母顺序排列。块 ID 必须是有效的 base64 字符串,小于 64 字节并且每个块的长度相同。然后你就可以像你原来想的那样使用返回的阻止列表了。
您可以为每次调用传递增量 blockId(或 chunkId) blob.PutBlock:
var blockCount = 0;
...
var blockId = Convert.ToBase64String(BitConverter.GetBytes(blockCount));
blob.PutBlock(blockId, ms, null);
blocksCount++;
然后通过知道传输块的数量来提交它们:
var blockIds = Enumerable.Range(0, blocksCount).Select(b => Convert.ToBase64String(BitConverter.GetBytes(b)));
blob.PutBlockList(blockIds);
我有一个批量上传系统,我想执行以下操作:
- 将一大块数据上传到服务器,服务器会将其作为块 blob 上的未提交块。
- 上传者对 block/blob 实现一无所知。它只知道它正在存储一大块数据。
- 服务器也无法在调用之间保留任何状态。
- 一旦所有块都已上传(上传者在最后一个块上设置标志),服务器将:
- 获取 blob 上未提交块的列表(请记住,它无法保留状态,因此无法将此列表保存在内存中)然后
- 调用以提交它们 (PutBlockList)。 它们必须按正确的顺序提交。
但是从 API 返回的块的顺序不是文档所说的顺序。
根据 Azure 存储 API 站点,
The list of uncommitted blocks is returned beginning with the most recently uploaded block to the oldest uploaded block. (https://msdn.microsoft.com/en-us/library/azure/dd179400.aspx , under the Remarks section at the bottom)
但是,原始 API 调用和 Microsoft Azure 存储 SDK 都按字母顺序返回块,而不是按它们以任何方式上传的顺序。
我是不是看错了文档?这可能是 API 中的错误吗?本地存储模拟器也给出了相同的结果。
谢谢!
我们检查了存储服务端的内容,结果是:文档有一个错误。从第 1 天开始,未提交块列表按字母顺序返回。我们将尽快更新 MSDN 文档以消除错误,对于给您带来的不便,我们深表歉意!
这里有一些解决问题的方法:
- 如果您无法在本地保存任何状态,请尝试与您的 put 块调用并行将块 ID 存储在云中。我建议使用 append blob 来存储这些。
探索其他一些 blob 类型。
如果您想按上传顺序写入数据,附加 blob 总体上可能更好。追加 blob 具有与块 blob 相同的读取行为和吞吐量,但不允许您更新或删除已经放置的块。但是,要附加数据,您需要做的就是一个 appendBlock ,这将添加到 blob 的末尾——不需要提交!
页 blob 还允许您在不提交的情况下放置数据。与附加 blob 不同,它们将允许在 blob 的中间进行修改。但是,它们对可被 512 整除的数据长度有严格限制。因此,如果这不是您数据的自然 属性,则您需要处理填充。
SDK 对附加和页面有很好的分块支持,您只需将数据放入其中,数据就会被放入。对于块当然也有分块,但状态是在客户端维护的。
- 按照字母顺序排列 属性 并使您的块 ID 按字母顺序排列。块 ID 必须是有效的 base64 字符串,小于 64 字节并且每个块的长度相同。然后你就可以像你原来想的那样使用返回的阻止列表了。
您可以为每次调用传递增量 blockId(或 chunkId) blob.PutBlock:
var blockCount = 0;
...
var blockId = Convert.ToBase64String(BitConverter.GetBytes(blockCount));
blob.PutBlock(blockId, ms, null);
blocksCount++;
然后通过知道传输块的数量来提交它们:
var blockIds = Enumerable.Range(0, blocksCount).Select(b => Convert.ToBase64String(BitConverter.GetBytes(b)));
blob.PutBlockList(blockIds);