Satya 向您演示如何
执行到 S3 的
分段消息上传

Satya_s3-multipart-upload-cli-1

我想将一个大文件 (超过 100 MB) 分成多段复制到 Amazon Simple Storage Service (Amazon S3) 存储桶。此外,我还想在文件段上传并重新连接成原始文件后确认文件的完整性。如何使用 AWS 命令行界面 (CLI) 实现上述操作?

将文件分成多段上传到 Amazon S3 可以提高上传速度,因为您使用多个线程来并行上传文件段。另一个好处是,如果一个或多个段上传失败,您只需重新上传这些失败的段而无需重新上传整个文件。

要在启动上传时验证分段消息上传的完整性,可以将原始文件以及各个文件段的 base64 MD5 校验和值发送到 Amazon S3。这些校验和值可以用来验证文件或任一文件段的完整性。具体步骤如下:

  1. 获取要上传的文件的 base64 MD5 校验和。
  2. 将文件拆分成多个段,并获取每个文件段的 base64 MD5 校验和。
  3. 启动向 Amazon S3 的分段消息上传,然后接收具有唯一 UploadId 值的响应。该值将原始文件与各个文件段相关联。
  4. 将文件段上传到 Amazon S3,同时指定每个文件段的 UploadId 和 base64 MD5 校验和。Amazon S3 会为每个文件段返回不同的 ETag 值。
  5. 上传完所有段后,运行一项命令以完成分段上传过程。此命令包含几项详细信息,例如,目标存储桶、文件段列表以及其他信息。Amazon S3 使用此信息来重新创建原始文件并验证其完整性。

使用 AWS CLI 完成以下步骤,以将文件以分段消息的形式上传到 Amazon S3 存储桶。

注意:可通过在多种操作系统上运行的几个不同的命令处理程序来访问 AWS CLI。命令处理程序通常采用不同的语法规则来接受参数值。例如,有些命令处理程序处理双引号文本,而有些则仅接受单引号文本。本文档中的输入和输出示例是在运行 AWS CLI 时使用 Windows 命令提示符创建的。Linux、MacOS 和 Windows PowerShell 使用不同的语法。有关更多信息,请参阅为 AWS CLI 指定参数值

第 1 步:获取要上传的文件的 base64 MD5 校验和

使用 Windows - 下载 File Checksum Integrity Verifier (FCIV) 实用程序并将内容提取到某个文件夹。在提升权限 (以管理员身份运行) 命令提示符中运行以下命令,将文件夹位置添加到 Windows 系统路径 (将 c:\fciv 替换为提取的 FCIV 实用程序文件所在的文件夹):

C:>set path=%path%;c:\\fciv

注意:如果通过命令提示符修改 Windows 系统路径,则在 Windows 重启后更改会丢失。要永久修改 Windows 系统路径环境变量,请查阅 Windows 文档或在 Internet 上搜索“更改 Windows X 路径变量”(将 X 替换为您的 Windows 版本)。

安装 FCIV 实用程序并使用提取的 FCIV 实用程序文件位置更新 %path% 环境变量,然后运行此命令返回要上传到 Amazon S3 的文件的十六进制 MD5 校验和。将 c:\S3\testfile 替换为要上传到 Amazon S3 的文件的位置:

fciv.exe c:\\S3\\testfile

注意:如果文件路径包含空格,请为路径加上引号 (")。

以下命令计算文件 C:\Windows\explorer.exe 的 MD5 校验和,计算其他文件时也将返回类似的值:

fciv C:\\Windows\\explorer.exe
//
// File Checksum Integrity Verifier version 2.05.
//
e1b0af69bfb6cbde9b53c55e4bf91992 c:\\windows\\explorer.exe

重要提示:FCIV 实用程序返回的 MD5 校验和为十六进制,必须转换为 base64,然后才能用作向 Amazon S3 上传分段消息的校验和值。如果使用十六进制 MD5 校验和,会出现错误消息“The Content-MD5 you specified is invalid”(您指定的 Content-MD5 无效)。Internet 上有多种十六进制到 base64 的字符串解码器。此外,您还可以下载脚本代码 (例如 HexToBase64 VB 脚本)。如果您计划广泛使用向 Amazon S3 上传分段消息,可以查找在电子表格中使用十六进制到 base64 的转换函数示例。在本例中,FCIV 实用程序返回的十六进制值的 base64 编码对等项为 4bCvab+2y96bU8VeS/kZkg==

使用 Linux - Linux 允许您使用 openssl 命令计算文件的 base64 MD5 校验和。要在 Linux 中确定文件的 base64 MD5 校验和,请从 Linux shell 运行以下命令:

openssl md5 -binary PATH/TO/FILE |base64 

以下命令检索文件 /bin/bash 的 base64 MD5 校验和,检索其他文件时也将返回类似的值:

user@example:/home$ openssl md5 -binary /bin/bash |base64
+e9lnJtCrdoKwYqg9wlFwA==

使用 Windows - 您可以在 Windows 中使用可用的免费实用程序 (例如 HJ-Split for Windows) 将一个文件拆分为多个段。HJ-Split for Windows 也提供了一个用于为每个文件段计算十六进制 MD5 校验和值的用户界面。由于这些校验和值是十六进制值,您必须先将其转换为 base64,然后才能将其用于上传分段消息。

使用 Linux - Linux 本身可以使用 split 命令拆分文件,并且还可以计算 base64 MD5 校验和。有关如何使用 Linux split 命令的更多信息,请在 Linux 命令 shell 中输入一个或多个以下命令:

split --help - displays arguments for the split command
info split - displays general information about the split command
man split - displays the manual page for the split command

如果您要使用 GUI 界面,HJ-Split 也可以用于 Linux。

下表显示了启动分段消息上传所需的信息。

项目

参数和值

目标存储桶

--bucket targetBucket

文件名称

--key testfile  --metadata md5=mvhFZXpr7J5u0ooXDoZ/4Q==

第 1 部分

--part-number 1  --body testfile.001 --content-md5 Vuoo2L6aAmjr+4sRXUwf0w==

第 2 部分

--part-number 2  --body testfile.002  --content-md5 317wIkbjGrgH2m9igCwa6A==

使用表中的信息,可以运行 AWS CLI 命令 aws s3api create-multipart-upload 来检索将原始文件与文件段相关联的唯一 UploadId 值。

aws s3api create-multipart-upload --bucket multirecv --key testfile
--metadata md5= mvhFZXpr7J5u0ooXDoZ/4Q==

以下命令响应包含在上传消息段时需要的 UploadId 值:

}    "Key": "testfile"
    "Bucket": "multirecv",    
    "UploadId":"sDCDOJiTUVGeKAk3Ob7qMynRKqe3ROcavPRwg92eA6JPD4ybIGRxJx9R0VbgkrnOVphZFK59KCYJAO1PXlrBSW7vcH7ANHZwTTf0ovqe6XPYHwsSp7eTRnXB1qjx40Tk",
{

在以下示例中,用于上传第一个消息段的命令会指定目标存储桶、原始文件名称、第一个文件段、UploadId 值,以及第一个文件段的 base64 MD5 校验和:

aws s3api upload-part --bucket multirecv --key testfile --part-number 1 --body testfile.001 --upload-id sDCDOJiTUVGeKAk3Ob7qMynRKqe3ROcavPRwg92eA6JPD4ybIGRxJx9R0VbgkrnOVphZFK59KCYJAO1PXlrBSW7vcH7ANHZwTTf0ovqe6XPYHwsSp7eTRnXB1qjx40Tk --content-md5 Vuoo2L6aAmjr+4sRXUwf0w==

以下命令响应包含此消息段的 ETag 值:保存要在稍后使用的 ETag 值,以完成分段消息上传过程:

{
    "ETag": "\\"56ea28d8be9a0268ebfb8b115d4c1fd3\\""
}

用于上传第二个消息段的命令与第一个类似,不同之处在于段编号 (--part-number 2)、第二段的名称 (--body testfile.002) 以及 MD5 校验和值不同:

aws s3api upload-part --bucket multirecv --key testfile --part-number 2 --body testfile.002 --upload-id sDCDOJiTUVGeKAk3Ob7qMynRKqe3ROcavPRwg92eA6JPD4ybIGRxJx9R0VbgkrnOVphZFK59KCYJAO1PXlrBSW7vcH7ANHZwTTf0ovqe6XPYHwsSp7eTRnXB1qjx40Tk --content-md5 317wIkbjGrgH2m9igCwa6A==

用于上传第二个消息段的命令返回不同的 ETag 值:

{
    "ETag": "\\"df5ef02246e31ab807da6f62802c1ae8\\""
}

或者,运行以下命令列出已成功上传的段:

aws s3api list-parts --bucket multirecv --key testfile --upload-id sDCDOJiTUVGeKAk3Ob7qMynRKqe3ROcavPRwg92eA6JPD4ybIGRxJx9R0VbgkrnOVphZFK59KCYJAO1PXlrBSW7vcH7ANHZwTTf0ovqe6XPYHwsSp7eTRnXB1qjx40Tk

在本例中,系统将返回以下输出。以下输出描述了账户所有者、分段消息上传的发起者、已上传的段,以及段所在存储桶的存储类:

{
    "Owner": {
        "DisplayName": "multipartmessage",
        "ID": "290xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    },
    "Initiator": {
        "DisplayName": "multipart",
        "ID": "arn:aws:iam::22xxxxxxxxxx:user/multipart"
    },
    "Parts": [
        {
            "LastModified": "2016-01-13T13:43:33.000Z",
            "PartNumber": 1,
            "ETag": "\\"56ea28d8be9a0268ebfb8b115d4c1fd3\\"",
            "Size": 79520768
        },
        {
            "LastModified": "2016-01-13T13:56:47.000Z",
            "PartNumber": 2,
            "ETag": "\\"df5ef02246e31ab807da6f62802c1ae8\\"",
            "Size": 79519704
        }
    ],
    "StorageClass": "STANDARD"
}

上传段后,Amazon S3 需要一些附加信息才能重新创建原始文件。第一段信息应当采用 JSON 格式文件的形式,该文件包含早期在上传消息段时返回的 ETag 值。在本例中,该文件的名称为 fileparts 并且与原始文件和组成的文件段保存在同一个目录中:

# fileparts
{
    "Parts": [
    {
        "ETag": "56ea28d8be9a0268ebfb8b115d4c1fd3",
        "PartNumber":1
    },
    {
        "ETag": "df5ef02246e31ab807da6f62802c1ae8",
        "PartNumber":2
    }
    ]
}

分段消息上传过程完成。以下命令通过读取您在第 4 步中创建的 JSON 格式文件来确定每个文件段,并尝试将文件重新拼回为原始文件并保存在指定的 S3 存储桶中。此外,还会指定 –upload-id 参数,以便唯一标识分段文件的各个段。

aws s3api complete-multipart-upload --multipart-upload file://fileparts --bucket multirecv --key testfile --upload-id sDCDOJiTUVGeKAk3Ob7qMynRKqe3ROcavPRwg92eA6JPD4ybIGRxJx9R0VbgkrnOVphZFK59KCYJAO1PXlrBSW7vcH7ANHZwTTf0ovqe6XPYHwsSp7eTRnXB1qjx40Tk

如果最后这一步成功完成,则输出将如下所示:

{
    "ETag": "\\"13115fdae01633ff0af167d925cad279-2\\"",
    "Bucket": "multirecv",
    "Location": "https://multirecv.s3.amazonaws.com/testfile",
    "Key": "testfile"
}

运行以下命令以在上传的文件中检索对象标头数据:

aws s3api head-object --bucket multirecv --key testfile
{
    "AcceptRanges": "bytes",
    "ContentType": "binary/octet-stream",
    "LastModified": "Wed, 13 Jan 2016 13:15:00 GMT",
    "ContentLength": 159040472,
    "ETag": "\\"13115fdae01633ff0af167d925cad279-2\\"",
    "Metadata": {
        "md5": "mvhFZXpr7J5u0ooXDoZ/4Q=="
    }
}

如果在上传分段消息的一个或多个段时遇到问题,可以尝试按照第 4 步中所述重新上传消息段。如果某个消息段已上传,但被搁置,请确保将其删除以免产生不必要的存储费用。要列出存储桶中未完成的分段消息上传,请运行以下命令并将 targetBucket 替换为您的存储桶的名称:

aws s3api list-multipart-uploads --bucket multirecv

响应会列出尚未处理的所有消息段。

{
    "Uploads": [
        {
            "Initiator": {
                "DisplayName": "myaccount",
                "ID": "5b7xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx "
            },
            "Initiated": "2016-03-31T06:13:15.000Z",
            "UploadId": "MuQzVbEvQpHp7eHc_J5s9U.kzM3GAHeOJh1P8wVTmRqEVojwiwu3wPX6fWYzADNtOHklJI6W6Q9NJUYgjePKCVpbl_rDP6mGIr2AQJNKB_A-",
            "StorageClass": "STANDARD",
            "Key": "music.mp4",
            "Owner": {
                "DisplayName": " myaccount ",
                "ID": "5b7xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx "
            }
        }
   ]
}

您可以通过此信息来删除不需要的消息段。例如,要中止示例中所述的消息段,请运行以下命令:

aws s3api abort-multipart-upload --bucket multirecv --key music.mp4 --upload-id MuQzVbEvQpHp7eHc_J5s9U.kzM3GAHeOJh1P8wVTmRqEVojwiwu3wPX6fWYzADNtOHklJI6W6Q9NJUYgjePKCVpbl_rDP6mGIr2AQJNKB

此页面对您有帮助吗? |

返回 AWS Support 知识中心

需要帮助?请访问 AWS 支持中心

发布时间:2016 年 1 月 25 日

更新时间:2018 年 2 月 22 日