亚马逊AWS官方博客

如何使用AWS 命令行分段上传大文件

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命令的参数说明如下:

1.   -b参数指定分割文件大小;

2.   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之前,在甲骨文中国担任资深售前工程师,负责售前方案咨询和架构设计,在数据库,中间件,大数据及企业应用方面有丰富经验。