我正在使用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,但在快速查看源代码后,我不清楚它是否用于验证整个远程文件。
答案 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是:
总结,阻止上传时,取决于x-ms-blob-content-md5是否有值。