概述
您可以通过 AWS CLI,使用 aws s3 命令(高级别)或 aws s3api 命令(低级别)将大文件上传到 Amazon S3。有关这两个命令层的更多信息,请参阅结合使用 Amazon S3 与 AWS CLI。
最佳实践是使用 aws s3 命令(例如 aws s3 cp)进行上传和下载,因为这些 aws s3 命令会根据文件大小自动执行分段上传和下载。相比之下,只有在 aws s3 命令不支持特定上传需求(例如,当分段上传涉及多个服务器时,手动停止分段上传并稍后恢复)或者 aws s3 命令不支持所需的请求参数时,才应使用 aws s3api 命令(例如 aws s3api create-multipart-upload)。
使用低级别 (aws s3api) 命令分段上传文件
要使用高级别 aws s3 命令执行分段上传,请运行以下命令:
$ aws s3 cp large_test_file s3://DOC-EXAMPLE-BUCKET/
此示例使用命令 aws s3 cp,但其他涉及将对象上传到 S3 存储桶的 aws s3 命令(例如,aws s3 sync 或 aws s3 mv)在对象非常大的情况下都会自动执行分段上传。
分段上传到 Amazon S3 的对象具有与使用传统 PUT 请求上传的对象不同的 ETag 格式。要存储源文件的 MD5 校验和值作为参考,将带校验和值的文件作为自定义元数据上传。要将 MD5 校验和值添加为自定义元数据,请在上传命令中包含可选参数 --metadata md5="examplemd5value1234/4Q",类似于以下内容:
aws s3 cp large_test_file s3://DOC-EXAMPLE-BUCKET/ --metadata md5="examplemd5value1234/4Q"
要在上传期间使用更多主机带宽和资源,增加 AWS CLI 配置中设置的最大并发请求数。默认情况下,AWS CLI 使用 10 个最大并发请求。以下命令将最大并发请求数设置为 20:
aws configure set default.s3.max_concurrent_requests 20
重要提示:只有在 aws s3 命令不支持特定上传需求(例如,当分段上传涉及多个服务器时,手动停止分段上传并恢复)或者 aws s3 命令不支持所需的请求参数时,才使用此 aws s3api 过程。对于其他分段上传,请使用 aws s3 cp 或其他高级别 s3 命令。
使用低级别(aws s3api)命令分段上传
1. 将要上传的文件拆分为多个部分。提示:如果您使用的是 Linux 操作系统,则使用 split 命令。
2. 运行此命令以启动分段上传并检索关联的上传 ID。该命令会返回一个包含 UploadID 的响应:
aws s3api create-multipart-upload --bucket [bucketname] --key [objectname] --endpoint [url]
3. 复制 UploadID 值作为后续步骤的参考信息。
4. 运行此命令以上传文件的第一部分。请务必使用适合您的存储桶、文件和分段上传的值来替换所有值。该命令会返回一个响应,其中包含您上传的文件部分的 ETag 值。
aws s3api upload-part --bucket [bucketname] --key [objectname] --part-number 1 --body [filename] --upload-id [UploadId] --content-md5 [md5]
5. 复制 ETag 值,以便在后面的步骤中用作参考。
6. 对文件的每个部分重复步骤 4 和 5。对于您上传的每个新部分,请务必递增部分编号。
7. 上传所有文件部分后,运行以下命令列出上传的部分并确认列表已完成:
aws s3api list-parts --bucket DOC-EXAMPLE-BUCKET --key large_test_file --upload-id exampleTUVGeKAk3Ob7qMynRKqe3ROcavPRwg92eA6JPD4ybIGRxJx9R0VbgkrnOVphZFK59KCYJAO1PXlrBSW7vcH7ANHZwTTf0ovqe6XPYHwsSp7eTRnXB1qjx40Tk
8. 将上传的每个文件部分的 ETag 值编译为类似于以下内容的 JSON 格式文件:
"Parts": [{
"ETag": "example8be9a0268ebfb8b115d4c1fd3",
"PartNumber":1
},
....
{
"ETag": "example246e31ab807da6f62802c1ae8",
"PartNumber":4
}]
}
9. 将文件命名为 fileparts.json。
10. 运行此命令来完成分段上传。将 --multipart-upload 的值替换为包含您创建的 ETag 的 JSON 格式文件的路径。
aws s3api complete-multipart-upload --multipart-upload file://fileparts.json --bucket DOC-EXAMPLE-BUCKET --key large_test_file --upload-id exampleTUVGeKAk3Ob7qMynRKqe3ROcavPRwg92eA6JPD4ybIGRxJx9R0VbgkrnOVphZFK59KCYJAO1PXlrBSW7vcH7ANHZwTTf0ovqe6XPYHwsSp7eTRnXB1qjx40Tk
11. 如果上一个命令成功,则会收到类似于下面的响应:
{
"ETag": "\\"exampleae01633ff0af167d925cad279-2\\"",
"Bucket": "DOC-EXAMPLE-BUCKET",
"Location": "https://DOC-EXAMPLE-BUCKET.s3.amazonaws.com/large_test_file",
"Key": "large_test_file"
}
解决上传失败的问题
如果您使用高级别 aws s3 命令进行分段上传并且上传失败(由于超时或手动取消),则必须启动新的分段上传。在大多数情况下,AWS CLI 会自动取消分段上传,然后删除您创建的所有分段上传文件。此过程可能耗时数分钟。
如果您使用 aws s3api 命令进行分段上传并且该过程中断,则必须删除上传的未完成部分,然后重新上传这些部分。
要删除未完成部分,使用 AbortIncompleteMultipartUpload 生命周期操作。或者,按照以下步骤使用 aws s3api 命令删除未完成部分:
1. 运行此命令列出未完成的分段文件上传。将 --bucket 值替换为您的存储桶的名称。
aws s3api list-multipart-uploads --bucket DOC-EXAMPLE-BUCKET
2. 该命令会返回一条消息,其中包含未处理的任何文件部分,类似于以下内容:
{
"Uploads": [
{
"Initiator": {
"DisplayName": "multipartmessage",
"ID": "290xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
"
},
"Initiated": "2016-03-31T06:13:15.000Z",
"UploadId": "examplevQpHp7eHc_J5s9U.kzM3GAHeOJh1P8wVTmRqEVojwiwu3wPX6fWYzADNtOHklJI6W6Q9NJUYgjePKCVpbl_rDP6mGIr2AQJNKB_A-",
"StorageClass": "STANDARD",
"Key": "",
"Owner": {
"DisplayName": "multipartmessage",
"ID": "290xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx "
}
}
]
}
3. 运行此命令删除未完成的部分:
aws s3api abort-multipart-upload --bucket DOC-EXAMPLE-BUCKET --key large_test_file --upload-id examplevQpHp7eHc_J5s9U.kzM3GAHeOJh1P8wVTmRqEVojwiwu3wPX6fWYzADNtOHklJI6W6Q9NJUYgjePKCVpbl_rDP6mGIr2AQJNKB