1.S3 上传文件介绍
使用亚马逊云的朋友经常需要上传文件到 S3 存储,亚马逊 S3 提供了在单个操作中上传文件和分段上传文件两种方式。使用单个操作上传,每次可以上传最大 5GB 的文件。如果使用分段上传来上传文件,可以 上传最大大小为 5TB 的文件。
2.分段上传的概念及其优势
分段上传允许将一个文件分割成多个分段 ,您可以按任意顺序上传这些文件分段。如果任意分段传输失败,可以重新传输该分段且不会影响其他分段。当对象的所有段都上传后,S3 可以使用这些分段创建对象。一般而言,如果您的文件大小达到了 100 MB,您应该考虑使用分段上传,而不是在单个操作中上传文件。
分段上传的优势主要有以下几点:
提高吞吐量
如果需要上传的文件比较大,使用直接上传方式,效率很低。而使用亚马逊 S3 分段上传功能,通过并行上传分段以提高吞吐量,能充分利用当前的带宽,提高了上传效率。
从网络问题中快速恢复
如果使用分段上传,某个分段失败了,你只需要重新上传这个分段,将上传文件时由于网络错误所产生的影响降至最低。
突破 S3 单文件上传限制
当文件大于 5GB,你只能将文件分片,然后分段上传。
3.S3 分段上传的核心规范
S3 分段上传的部分指标如下表所示:
4. S3 分段上传的权限配置
使用 S3 分段上传需要适当的权限配置,相比于 S3 的单文件上传,S3 在分段上传时需要部分额外的权限,最低的 S3 分段上传权限配置如下所示:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:AbortMultipartUpload",
"s3:GetObject",
"s3:ListBucketMultipartUploads",
"s3:ListMultipartUploadParts",
"s3:PutObject"
],
"Resource": [
"*"
]
}
]
}
具体 AWS API 分段上传的权限要求,请参考 AWS 官方文档:https://docs.aws.amazon.com/zh_cn/AmazonS3/latest/dev/mpuAndPermissions.html
5. 使用 AWS CLI 的自动分段上传
使用 AWS 的 s3 cp 命令和 s3 sync 等命令可以自动对要上传的大文件分片,然后上传。下面以一个视频文件 myvideo.mp4 为例,详细介绍如何使用 s3 cp 命令将文件分段上传到 AWS 北京区域。
第一步:配置 AWS 命令行(CLI)环境
使用命令行上传 S3 文件,首先要安装 AWS CLI 环境,AWS CLI 是管理和访问 AWS 服务的工具,AWS CLI 可以安装在 Windows、OSX、Linux、Unix 等多种环境上,关于如何安装 CLI 环境,也可以参考下面链接:
http://docs.aws.amazon.com/zh_cn/cli/latest/userguide/cli-chap-welcome.html
完成 CLI 的安装后,首先运行下面命令配置 CLI 环境:
[ec2-user@ip-192-10-x-xxx mnt]$ aws configure
命令输出内容如下:
AWS Access Key ID [********************]:
AWS Secret Access Key [********************]:
Default region name [None]:
Default output format [None]:
如上示例可以看到,运行 aws configure 后,需要输入下面四个参数:
AWS Access Key ID
要访问 AWS 的资源,需要配置用户认证信息。在 AWS CLI 中可以通过访问密钥来实现用户认证。本例通过访问密钥来实现认证,如果您还没有为用户生成访问密钥,可以在 AWS console 中,选择“用户”后,可以看到“Security Credentials”的选项,点击“Create Access Key”就可以为用户生成访问的 Key ID 和 Access Key,你可以下载生成的 Excel 密钥文件,查看 Access Key ID 和 Secret Access Key 的值。另外,请确保您生成密钥的用户具有访问 S3 的相关权限。最低的 S3 分段上传权限配置在文档的前半部分已经介绍。
AWS Secret Access Key:
查看用户生成的密钥文件并输入 Access Key 的值。
Default region name:
默认区域名称。这是您希望默认对其进行调用的区域的名称。由于在本用例中我们需要调用北京区域的 S3 服务,因此请输入 cn-north-1。
Default output format
默认输出格式,此格式可以是 json、文本或表。如果不指定输出格式,将使用 json。这里我们使用默认的 json 选项。
第二步:运行复制命令
运行 s3 cp 命令如下:
[ec2-user@ip-192-10-x-xxx data]$ aws s3 cp myvideo.mp4 s3://multiple-upload-test/myvideo.mp4
上面我们使用 cp 命令将 myvideo.mp4 文件上传到北京区multiple-upload-test
存储桶中,输出信息如下:
upload: ./myvideo.mp4 to s3://multiple-upload-test/myvideo.mp4
在命令运行过程中,你可以看到文件自动被分成多个片段然后分段上传到目标存储通,上传完成后,你就可以在目标存储桶中看到完整的文件。使用 aws s3 sync 也可以实现自动的分段上传。
6.使用 AWS CLI 的手工分段上传
在有些情况下,您可能希望手工分段上传文件到 S3,下面还是以视频文件 myvideo.mp4 为例,介绍如何将大文件手工分段然后上传到 AWS 北京区域。
第一步:配置 AWS 命令行(CLI)环境
请参考上一节配置 CLI 环境,如果已经配置好环境,可以直接进入第二步。
第二步:将文件分割成多个分片
目前需要上传 myvideo.mp4,使用 ls 命令查看要上传的文件,如下所示:
[ec2-user@ip-192-10-x-xxx data]$ ls -l
total 76272
-rwxrwxrwx 1 ec2-user ec2-user 78102279 Jun 24 06:51 myvideo.mp4
可以看到目前文件大概 78M,使用 split 命令将文件分成 40M 大小的文件。
split -b 40m myvideo.mp4 myvideo-part-
split 命令的参数说明如下:
-b 参数指定分割文件大小;
myvideo-part-是指定生成分割文件的文件名前缀。
当运行完命令后,我们查看当前目录,即可发现生成的分割片段。
[ec2-user@ip-192-10-0-232 data]$ ls -l
total 152544
-rwxrwxrwx 1 ec2-user ec2-user 78102279 Jun 24 06:51 myvideo.mp4
-rw-rw-r-- 1 ec2-user ec2-user 41943040 Jun 24 06:57 myvideo-part-aa
-rw-rw-r-- 1 ec2-user ec2-user 36159239 Jun 24 06:57 myvideo-part-ab
可以看到 split 命令将 myvideo.mp4 分割成两个以 myvideo-part-开头的分片文件。
第三步:初始化分段上传
使用 AWS 分段上传 create-multipart-upload 命令启动分段上传,运行下面命令:
aws s3api create-multipart-upload --bucket multiple-upload-test --key myvideo.mp4
其中:
bucket:要上传 S3 的 bucket 名称;
key:要上传文件的名称。
运行命令后返回信息如下:
{
"Bucket": " multiple-upload-test",
"UploadId": "_m6b1l5DMGTl_a6rkmhrUxMaqlzzY6CICEVS4gEXlXv7PWHBIZTi90RrmNQclc6PRRnYzCaA6auA5pDaH4p13Bp8xyuCtwwLVl_xeU1yiX0KOQNhMzbE7_1AMA0WM7uO",
"Key": "myvideo.mp4"
}
看到返回具体的 UploadId 则说明初始化分段上传成功,后续我们需要使用 UploadId 来完成上传分段文件的各项操作,因此请妥善保管该 UploadId。
启动分段上传后,可以使用 list-multipart-uploads 命令查看分段上传具体信息,示例如下:
aws s3api list-multipart-uploads --bucket multiple-upload-test
同样地,当中的 bucket 为要上传 S3 的 bucket 名称,与上述命令一致。
返回信息:
{
"Uploads": [
{
"Initiator": {
"DisplayName": "xxxxxxx",
"ID": "arn:aws-cn:iam::xxxxxxxx:user/xxxxx"
},
"Initiated": "2016-06-24T07:17:28.000Z",
"UploadId": "_m6b1l5DMGTl_a6rkmhrUxMaqlzzY6CICEVS4gEXlXv7PWHBIZTi90RrmNQclc6PRRnYzCaA6auA5pDaH4p13Bp8xyuCtwwLVl_xeU1yiX0KOQNhMzbE7_1AMA0WM7uO",
"StorageClass": "STANDARD",
"Key": "myvideo.mp4",
"Owner": {
"ID": "9ad8x098aa27467exxxf6f04d5eaxxx6e6e93d5067ba5bdd86dbb68ddb2511bd"
}
}
]
第四步:上传文件分片
首先上传第一个分片文件,命令如下:
aws s3api upload-part --bucket multiple-upload-test --key myvideo.mp4 --part-number 1 --body myvideo-part-aa --upload-id _m6b1l5DMGTl_a6rkmhrUxMaqlzzY6CICEVS4gEXlXv7PWHBIZTi90RrmNQclc6PRRnYzCaA6auA5pDaH4p13Bp8xyuCtwwLVl_xeU1yiX0KOQNhMzbE7_1AMA0WM7uO
其中:
bucket:要上传 S3 的 bucket 名称;
key:要上传文件的名称。
part-number:当前上传分片文件的分段编号。(需要注意的是,上传分段时,除了指定上传 ID,还必须指定分段编号。您可以选择 1 和 10000 之间的任意分段编号。分段编号在您正在上传的数据元中唯一地识别分段及其位置。如果您使用之前上传的分段的同一分段编号上传新分段,则之前上传的分段将被覆盖。无论您何时上传分段,Amazon S3 都将在其响应中返回 ETag 标头。对于每个分段上传,您必须记录分段编号和 ETag 值。您需要在随后的请求中包括这些值以完成分段上传。这个参数很重要,当完成所有的分段上传后,S3 将按照分段编号从小到大的顺序把分段拼接起来。)
body:当前上传分片文件的本地路径。
upload-id:初始化分段上传时系统返回的 UploadId。
返回信息:
{
"ETag": "\"82eba7dcefdb5dd5bc72247c3f5543ca\""
}
看到返回码 ETag 则说明上传成功。
同样地,我们继续上传第二个分片文件,命令如下:
aws s3api upload-part --bucket multiple-upload-test --key myvideo.mp4 --part-number 2 --body myvideo-part-ab --upload-id _m6b1l5DMGTl_a6rkmhrUxMaqlzzY6CICEVS4gEXlXv7PWHBIZTi90RrmNQclc6PRRnYzCaA6auA5pDaH4p13Bp8xyuCtwwLVl_xeU1yiX0KOQNhMzbE7_1AMA0WM7uO
返回信息:
{
"ETag": "\"03902e3af09f974cd406f988587d0814\""
}
上传分段文件后,可以使用 list-parts 命令查看上传信息:
aws s3api list-parts --bucket multiple-upload-test --key myvideo.mp4 --upload-id _m6b1l5DMGTl_a6rkmhrUxMaqlzzY6CICEVS4gEXlXv7PWHBIZTi90RrmNQclc6PRRnYzCaA6auA5pDaH4p13Bp8xyuCtwwLVl_xeU1yiX0KOQNhMzbE7_1AMA0WM7uO
返回信息如下:
{
"Owner": {
"ID": "9ad8c098aa27467ec9ef6f04d5ea97a6e6e93d5067ba5bdd86dbb68ddb2511bd"
},
"Initiator": {
"DisplayName": "lanyong",
"ID": "arn:aws-cn:iam::xxxxxxxxxx:user/xxxxxx"
},
"Parts": [
{
"LastModified": "2016-06-24T07:34:21.000Z",
"PartNumber": 1,
"ETag": "\"82eba7dcefdb5dd5bc72247c3f5543ca\"",
"Size": 41943040
},
{
"LastModified": "2016-06-24T07:39:16.000Z",
"PartNumber": 2,
"ETag": "\"03902e3af09f974cd406f988587d0814\"",
"Size": 36159239
}
],
"StorageClass": "STANDARD"
}
在返回的信息中我们可以查看分段上传的所有者信息以及各分段的详细信息。在下述的完成文件组装中您需要用到各分段的 ETag 信息,您可以在本条命令的返回中获取。当然,在每次分段上传后也会返回 ETag 信息,您也可以把他们分别记录下来。
第五步:完成文件组装
所有分段都被上传后,S3 需要具体分段信息来重新组装原始文件,需要的内容包括每次上传的分段序号及上传后返回的 ETag。每个分段的文件序号和 ETag 可以从上个命令 list-parts 中获取。 获取的文件序号和 ETag 需要使用如下示例格式包装:
{
"Parts": [
{
"ETag": "82eba7dcefdb5dd5bc72247c3f5543ca",
"PartNumber": 1
},
{
"ETag": "03902e3af09f974cd406f988587d0814",
"PartNumber": 2
}
]
}
将上文本保存为文件,放于当前目录下。然后运行 complete-multipart-upload 命令完成文件的组装:
aws s3api complete-multipart-upload --multipart-upload file://mpustructs --bucket multiple-upload-test --key myvideo.mp4 --upload-id _m6b1l5DMGTl_a6rkmhrUxMaqlzzY6CICEVS4gEXlXv7PWHBIZTi90RrmNQclc6PRRnYzCaA6auA5pDaH4p13Bp8xyuCtwwLVl_xeU1yiX0KOQNhMzbE7_1AMA0WM7uO
当中的 mpustructs 为上述组装文件的文件名,用户可自定义。
返回信息:
{
"ETag": "\"45f9fd2960aa026c44eec4618bc592a2-2\"",
"Bucket": "multiple-upload-test",
"Location": "https://s3.cn-north-1.amazonaws.com.cn/multiple-upload-test/myvideo.mp4",
"Key": "myvideo.mp4"
}
完成分段上传后,Amazon S3 会按分段编号的升序顺序将各个段连接起来,从而创建对象。如果在开始分段上传请求中提供了任何数据元元数据,则 Amazon S3 会将该元数据与数据元相关联。成功完成请求后,分段将不再存在。
需要特别注意的是,启动分段上传并上传一个或多个分段之后,您必须完成或中止分段上传,才能停止收取上传的段的存储费用。只有在完成或中止分段上传之后,Amazon S3 才会释放段存储并停止向您收取段存储费用。具体的段存储费用,请参考 AWS 官方文档:http://aws.amazon.com/cn/s3/pricing/。
为了防止用户上传分段后没有完成或中止分段所产生的不必要费用,作为最佳实践,AWS 建议在分段上传操作中加入存储桶生命周期管理策略,在超过一定时间后,自动中止未完成的分段上传。具体存储桶生命周期策略的设置方法,请参考 AWS 官方文档:https://docs.aws.amazon.com/zh_cn/AmazonS3/latest/dev/mpuoverview.html#mpuploadpricing。
第六步:检查您 S3 bucket 中的文件
上传完成后,请检查您的 bucket,你就可以看到文件已成功上传并组装完成了。
7.总结
本文介绍了如何使用 AWS CLI 向 S3 分段上传大数据文件,以打破 S3 单文件上传的限制、提高网络吞吐量以及快速地从网络问题中得以恢复。除此之外,AWS 还提供包括 Java、PHP、.NET 等丰富的开发工具包以实现 S3 分段上传大文件,用户可以根据自己的需要选择不同的接入渠道。既然一切都准备就绪,那就开始吧。相信 S3 分段上传将有效地解决用户的大文件上传问题,提供更好的用户体验。
作者介绍
蓝勇
AWS 解决方案架构师,负责基于 AWS 的云计算方案架构的咨询和设计,同时致力于 AWS 云服务在国内的应用和推广,在 DR 解决方案、数据仓库、RDS 服务、企业应用、自动化运维等方面有着广泛的设计和实践经验。在加入 AWS 之前,在甲骨文中国担任资深售前工程师,负责售前方案咨询和架构设计,在数据库,中间件,大数据及企业应用方面有丰富经验。
本文转载自 AWS 技术博客。
原文链接:
https://amazonaws-china.com/cn/blogs/china/uploading-using-s3/
评论