【问题标题】:Amazon S3 Multipart Upload AsyncAmazon S3 分段上传异步
【发布时间】:2013-07-08 20:10:07
【问题描述】:

我正在使用 Amazon S3 分段上传,我了解到您可以并行上传文件的各个部分。但是,通过查看文档,我发现亚马逊对上传文件部分的响应不包含部件号。所以我的问题是,如果我异步上传文件的第 1 部分和文件的第 2 部分,那么我检查亚马逊的响应,我怎么知道响应是指文件的第 1 部分还是第 2 部分?

这是一个示例请求和响应。

Request:
PUT /my-movie.m2ts?partNumber=1&uploadId=VCVsb2FkIElEIGZvciBlbZZpbmcncyBteS1tb3ZpZS5tMnRzIHVwbG9hZR HTTP/1.1
Host: example-bucket.s3.amazonaws.com
Date:  Mon, 1 Nov 2010 20:34:56 GMT
Content-Length: 10485760
Content-MD5: pUNXr/BjKK5G2UKvaRRrOA==
Authorization: AWS AKIAIOSFODNN7EXAMPLE:VGhpcyBtZXNzYWdlIHNpZ25lZGGieSRlbHZpbmc=

***part data omitted***

Response:
HTTP/1.1 200 OK
x-amz-id-2: Vvag1LuByRx9e6j5Onimru9pO4ZVKnJ2Qz7/C1NPcfTWAtRPfTaOFg==
x-amz-request-id: 656c76696e6727732072657175657374
Date:  Mon, 1 Nov 2010 20:34:56 GMT
ETag: "b54357faf0632cce46e942fa68356b38"
Content-Length: 0
Connection: keep-alive
Server: AmazonS3

【问题讨论】:

    标签: asynchronous amazon-web-services amazon-s3 multipartform-data


    【解决方案1】:

    您在每个部分的响应中返回的 Etag 是您刚刚上传的部分的 md5sum。

    在您的示例中,除非我犯了错误,否则您的 Content-MD5 会解码为 a54357aff06328ae46d942af69146b38 ...所以我建议除非您的 MD5 计算、请求和响应有问题张贴实际上并不属于一起。

    我写的分段上传器是非常迂腐的,因为我用它来归档关键数据(如此迂腐,事实上,它实际上转身并在它认为分段后重新下载文件上传成功以绝对确定最终产品是完美的)...但是此实用程序通过调用按顺序提交部分,该调用会阻塞并且在响应返回之前不会返回...并且其健全性测试之一是比较本地计算的带有 Etag 的块的 MD5,如果它们不匹配,这是一个致命错误......所以除非你有相同的块,否则你似乎可以用这种方式关联这些部分。


    补充:

    我没有使用缺少的正文来计算 md5 :) 我拿了你的标题:

    Content-MD5: pUNXr/BjKK5G2UKvaRRrOA==
    

    从 base64 -> 二进制 -> 十六进制转换并得到 a54357aff06328ae46d942af69146b38。

    我通过将 2 个命令行实用程序串在一起来进行验证下载,如下所示:

    wget --server-response '$signed_url' -O - | md5sum
    

    这会下载文件并将字节传输到 md5sum 以计算校验和,因此我可以下载无限大的文件而无需使用任何磁盘空间和很少的内存。 wget 实用程序具有内置的重试功能,如果连接中断,它将尝试从中断的字节位置继续。该管道的输出是文件的 md5sum (stdout) 和服务器发送的标头以及进度表 (stderr)。我的实用程序捕获标准输出并进行比较,同时让标准错误泄漏到控制台进行观察。

    【讨论】:

    • 感谢您的回答,其实我昨天刚翻了一些论坛才发现ETag是MD5。我以前对此一无所知。这应该可以找出响应所指的部分,希望我不会遇到任何冲突。在我看来,亚马逊在回复中发回零件号会是一个更好的设计。
    • 还有一个关于下载文件的问题 我正在寻找一种从亚马逊下载大文件的有效方法 到目前为止,我正在考虑使用 HTTP 范围标头并一次请求文件块,所以如果出现中断,我可以从中断的地方继续下载。您是否发现下载大文件的任何加速?再次感谢。
    • 哦,对于上面的示例,MD5 不起作用,因为消息正文被故意遗漏了“部分数据省略”。仅供参考。
    • 我更新了答案...但您的 http 库似乎应该能够以某种方式关联对请求的响应...很难想象它真的有用。
    【解决方案2】:

    当您启动分段上传时,您在请求中包含部件号。 From the AWS multipart upload documentation:

    PUT /ObjectName?partNumber=PartNumber&uploadId=UploadId HTTP/1.1
    Host: BucketName.s3.amazonaws.com
    Date: date
    Content-Length: Size
    Authorization: Signature
    

    因此对于您刚刚上传的部分没有任何歧义。

    EDIT所以基本流程如下:

    1. 启动分段上传并获取 UploadId

    2. 上传所有部分 在平行下。在每个响应中,您将获得一个 ETag 标头 - 您需要 记住它和它附带的部件号,以便 AWS 可以 重新组装文件

    3. 然后发送所有 ETag 值和部分 编号并完成分段上传

    【讨论】:

    • 感谢您的回复我知道我上传了哪一部分,但如果我同时上传两个部分,那么我会收到来自亚马逊的回复我无法判断回复是否确认第 1 部分或第 2 部分。至少我看不到一种方法来判断哪个响应是针对文件的哪个部分的。
    • 好吧,我仍然理解所有这些。但是对于上面的第 2 部分,您如何知道 ETag 使用的零件号。例如,第 1 部分是 5MB,第 2 部分只有 2KB 我能保证首先收到第 1 部分的响应吗?
    • 每个请求都有来自 AWS 的相应响应。它是 HTTP - 请求将超时或成功或失败(最后两个请求会返回响应)。不,他们不能保证以发起请求的相同顺序回复 - 但上传的每个部分都不知道其他部分,所以没关系。如果您包含有关如何执行上传的一些详细信息,它可能会帮助我解释更好的帮助 - 是通过命令行工具吗?通过网络浏览器中的 JavaScript?
    • 我正在使用 C++ 与 Amazon S3 的异步套接字连接并使用 IO 完成端口。我只对所有请求和响应使用一个套接字。因此,如果我同时发送一个文件的两个部分,一个 5MB 和一个 2KB,显然 2KB 部分的发送速度会比前一个部分快得多,并且完成速度也快得多。当我收到来自 IO 完成端口的响应时,我不确定此响应是针对第 1 部分还是第 2 部分,我可以假设较小的部分发送得更快,但这不是一个安全的假设。
    猜你喜欢
    • 1970-01-01
    • 2017-08-23
    • 2014-10-14
    • 1970-01-01
    • 1970-01-01
    • 2015-12-28
    • 1970-01-01
    • 2014-06-14
    • 2015-06-25
    相关资源
    最近更新 更多