Microsoft.Azure.Storage.DataMovement MD5检查

时间:2018-02-28 05:13:18

标签: azure azure-storage

我正在使用Microsoft.Azure.Storage.DataMovement nuget包将多个非常大的(150GB)文件传输到Azure冷存储中 TransferManager.UploadDirectoryAsync

它工作得非常好,但我的过程中的一个障碍点是,在上传后我附加到FileTransferred事件并再次读取本地文件以计算md5校验和并将其与远程副本进行比较:

private void FileTransferredCallback(object sender, TransferEventArgs e)
{
    var sourceFile = e.Source.ToString();
    var destinationFile = (ICloudBlob) e.Destination;

    var localMd5 = CalculateMd5(e.Source.ToString());
    var remoteMd5 = destinationFile.Properties.ContentMD5;

    if (localMd5 == remoteMd5)
    {
        destinationFile.Metadata.Add(Md5VerifiedKey, DateTimeOffset.UtcNow.ToDisplayText());
        destinationFile.SetMetadata();
    }
}

它比它需要的速度慢,因为每个文件都被双重处理 - 首先是库,然后是我的MD5检查。

这项检查是否有必要,或者图书馆已经为我做了繁重的工作?我可以看到Md5HashStream,但在快速查看源代码后,我不清楚它是否用于验证整个远程文件。

2 个答案:

答案 0 :(得分:1)

请注意整个blob 的元数据blob.Properties.ContentMD5实际上是由 Microsoft.Azure.Storage.DataMovement 库根据其本地计算结果上传后设置的此blob的所有块,而不是 Azure存储Blob服务

每个块时,Content-MD5 HTTP header保证blob上传的数据完整性,而不是整个blob 的元数据blob.Properties.ContentMD5,因为当 Microsoft.Azure.Storage.DataMovement 库设置元数据时, Azure存储Blob服务并未真正验证该值(请检查the introduction of x-ms-blob-content-md5 HTTP header)。

blob.Properties.ContentMD5的主要目的是通过 Microsoft.Azure.Storage.DataMovement 库将blob下载回本地磁盘时验证数据的完整性(如果DownloadOptions.DisableContentMD5Validation是设置为false,这是默认行为。)

答案 1 :(得分:0)

  

这项检查是否有必要,或者图书馆已经为我做了沉重的工作?

根据我的知识,我们只需要检查blob是否有ContentMD5 propetry的值。

当使用Microsoft.Azure.Storage.DataMovement上传大文件时,它实际上由多个PutBlock请求加上一个PutBlockList请求组成。每个PutBlock请求只上传部分内容,因此MD5在此类请求中可能只适用于当前上传的内容,并且不能用作最终的blob MD5值。

PutBlockList请求的内容是上述所有上传块标识的列表,因此该请求的MD5值只能在此列表完整性检查中完成。

验证所有这些请求后,内容的完整性得到保证。为了提高性能,存储服务器不会汇总上一个请求中所有块的内容来计算整个blob的MD5值,而是提供一个特殊的请求头,x-ms-blob-content-md5,The end将此头属性值设置为blob的MD5值。所以客户端只要最终的PutBlockList请求将MD5值的全部内容设置为x-ms-blob-content-md5,那么确保验证,blob也具有MD5值

因此基于工作流程完整性的阻止上传MD5是:

  1. 上传的文件分为几部分
  2. 将每个块作为PutBlock请求发送,并将当前块的MD5值计算到Content-MD5标头
  3. 发送完所有块后,发送PutBlockList请求
  4. 计算整个上传文件的MD值并将其设置为x-ms-blob-content-md5
  5. 的头部
  6. 列出先前作为请求内容发送的块的标识
  7. 将块ID列表的MD5值设置为Content-MD5标题
  8. 然后将PutBlockList请求中的x-ms-blob-content-md5值分配给blob的MD5属性
  9. 总结,阻止上传时,取决于x-ms-blob-content-md5是否有值。