教程:通过分段上传来上传对象并验证其数据完整性
分段上传允许将单个对象作为一组分段上传。每个分段都是对象数据的连续部分。您可以独立上传以及按任意顺序上传这些对象分段。如果任意分段传输失败,可以重新传输该分段且不会影响其他分段。上传完所有的对象分段后,Amazon S3 将汇集这些分段并创建对象。一般而言,如果您的对象大小达到了 100 MB,您应该考虑使用分段上传,而不是在单个操作中上传对象。有关分段上传的更多信息,请参阅使用分段上传来上传和复制对象。有关分段上传的相关限制,请参阅 Amazon S3 分段上传限制。
可以使用校验和来验证资产在复制时是否未被更改。执行校验和包括使用算法按顺序迭代文件中的每个字节。Amazon S3 提供了多个校验和选项,用于检查数据的完整性。我们建议您将这些完整性检查作为持久性最佳实践加以执行,并确认每个字节在传输过程中都未经更改。Amazon S3 还支持以下算法:SHA-1、SHA-256、CRC32 和 CRC32C。Amazon S3 使用其中一个或多个算法来计算额外的校验和值,并将其存储为对象元数据的一部分。有关校验和的更多信息,请参阅检查对象完整性。
目标
在本教程中,您将学习如何在 AWS 命令行界面(AWS CLI)中使用分段上传和额外的 SHA-256 校验和将对象上传到 Amazon S3。您还将学习如何通过计算已上传对象的 MD5 哈希值和 SHA-256 校验和,来检查对象的数据完整性。
主题
先决条件
-
在开始本教程之前,请确保您有权访问要上传到的 Amazon S3 存储桶。有关更多信息,请参阅 创建桶。
-
您必须安装并配置了 AWS CLI。如果未安装 AWS CLI,请参阅《AWS Command Line Interface用户指南》中的 Install or update to the latest version of the AWS CLI。
-
或者,您可以从控制台中使用 AWS CloudShell 运行 AWS CLI 命令。AWS CloudShell 是一个基于浏览器、预先经过身份验证的 Shell,您可以直接从 AWS Management Console中启动它。有关更多信息,请参阅《AWS CloudShell 用户指南》中的 What is CloudShell? 和 Getting started with AWS CloudShell。
步骤 1:创建大文件
如果您已经准备好要上传的文件,则可以在本教程中使用该文件。否则,请使用以下步骤创建一个 15 MB 的文件。有关分段上传的相关限制,请参阅 Amazon S3 分段上传限制。
创建大文件
根据您使用的操作系统,使用以下命令之一来创建文件。
Linux 或 macOS
要创建 15 MB 的文件,请打开本地终端并运行以下命令:
dd if=/dev/urandom of=census-data.bin bs=1M count=15
此命令创建一个名为 census-data.bin
的文件,其中填充了随机字节,大小为 15 MB。
Windows
要创建 15 MB 的文件,请打开本地终端并运行以下命令:
fsutil file createnew census-data.bin 15728640
此命令创建一个名为 census-data.bin
的文件,其中包含任意数据,大小为 15 MB(15728640 字节)。
步骤 2:将文件拆分为多个文件
要执行分段上传,必须将大文件拆分为若干较小的分段。然后,可以使用分段上传过程来上传较小的分段。此步骤演示如何将步骤 1 中创建的大文件拆分为较小的分段。以下示例使用名为 census-data.bin
的 15 MB 文件。
将大文件拆分为多个分段
Linux 或 macOS
要将大文件分成 5 MB 的分段,请使用 split
命令。打开终端并运行以下命令:
split -b 5M -d census-data.bin census-part
此命令将 census-data.bin
拆分成名为 census-part**
的 5 MB 分段,其中 **
是从 00
开始的数字后缀。
Windows
要拆分大文件,请使用 PowerShell。打开 Powershell
$inputFile = "census-data.bin" $outputFilePrefix = "census-part" $chunkSize = 5MB $fs = [System.IO.File]::OpenRead($inputFile) $buffer = New-Object byte[] $chunkSize $fileNumber = 0 while ($fs.Position -lt $fs.Length) { $bytesRead = $fs.Read($buffer, 0, $chunkSize) $outputFile = "{0}{1:D2}" -f $outputFilePrefix, $fileNumber $fileStream = [System.IO.File]::Create($outputFile) $fileStream.Write($buffer, 0, $bytesRead) $fileStream.Close() $fileNumber++ } $fs.Close()
此 PowerShell 脚本以 5 MB 大小的分块读取大文件,并将每个分块写入一个带有数字后缀的新文件。
运行相应的命令后,您应该会在执行该命令的目录中看到各个分段。每个分段都有一个与其分段编号对应的后缀,例如:
census-part00 census-part01 census-part02
步骤 3:创建分段上传并指定额外的校验和
要开始分段上传过程,您需要创建分段上传请求。此步骤包括启动分段上传以及为数据完整性指定额外的校验和。以下示例使用 SHA-256 校验和。如果您想要提供描述正上传的对象的任何元数据,必须在请求中提供它以便开始分段上传。
注意
在本步骤和后续步骤中,本教程使用 SHA-256 额外算法。您可以选择为这些步骤使用其他的额外校验和,例如 CRC32、CRC32C 或 SHA-1。如果使用不同的算法,则必须在整个教程步骤中都使用该算法。
开始分段上传
在终端中,使用以下 create-multipart-upload
命令开始存储桶的分段上传。将
替换为实际存储桶名称。另外,请用您选择的文件名替换 amzn-s3-demo-bucket1
census_data_file
。上传完成后,此文件名将成为对象键。
aws s3api create-multipart-upload --bucket
amzn-s3-demo-bucket1
--key 'census_data_file
' --checksum-algorithm sha256
如果您的请求执行成功,您将看到如下 JSON 输出:
{ "ServerSideEncryption": "AES256", "ChecksumAlgorithm": "SHA256", "Bucket": "
amzn-s3-demo-bucket1
", "Key": "census_data_file", "UploadId": "cNV6KCSNANFZapz1LUGPC5XwUVi1n6yUoIeSP138sNOKPeMhpKQRrbT9k0ePmgoOTCj9K83T4e2Gb5hQvNoNpCKqyb8m3.oyYgQNZD6FNJLBZluOIUyRE.qM5yhDTdhz" }
注意
当您发送请求以开始分段上传时,Amazon S3 将返回具有上传 ID 的响应,此 ID 是分段上传的唯一标识符。无论您何时上传分段、列出分段、完成上传或停止上传,您都必须包括此上传 ID。后续步骤需要用到 UploadId
、Key
和 Bucket
值,因此请务必保存这些值。
此外,如果您将分段上传与额外的校验和结合使用,则分段编号必须是连续的。如果您使用不连续的分段编号,则 complete-multipart-upload
请求可能会导致 HTTP 500
Internal Server Error
。
步骤 4:上传分段上传的分段
在此步骤中,您将分段上传的各个分段上传到 S3 存储桶。使用 upload-part
命令单独上传每个分段。此过程要求为每个分段指定上传 ID、分段编号和要上传的文件。
上传分段
-
上传分段时,除了上传 ID,还必须使用
--part-number
参数来指定分段编号。您可以选择 1 和 10000 之间的任意分段编号。分段编号在您正在上传的对象中唯一地识别分段及其位置。您选择的分段编号必须为连续序列(例如,它可以是 1、2 或 3)。如果您使用之前上传的分段的同一分段编号上传新分段,则之前上传的分段将被覆盖。 -
使用
upload-part
命令来上传分段上传的每个分段。--upload-id
与步骤 3 中create-multipart-upload
命令创建的输出内容相同。要上传数据的第一个分段,请使用以下命令:aws s3api upload-part --bucket
amzn-s3-demo-bucket1
--key 'census_data_file
' --part-number1
--bodycensus-part00
--upload-id "cNV6KCSNANFZapz1LUGPC5XwUVi1n6yUoIeSP138sNOKPeMhpKQRrbT9k0ePmgoOTCj9K83T4e2Gb5hQvNoNpCKqyb8m3.oyYgQNZD6FNJLBZluOIUyRE.qM5yhDTdhz
" --checksum-algorithmSHA256
完成每个
upload-part
命令后,您应该会看到类似以下示例的输出:{ "ServerSideEncryption": "AES256", "ETag": "\"e611693805e812ef37f96c9937605e69\"", "ChecksumSHA256": "QLl8R4i4+SaJlrl8ZIcutc5TbZtwt2NwB8lTXkd3GH0=" }
-
对于后续分段,相应地递增分段编号:
aws s3api upload-part --bucket
amzn-s3-demo-bucket1
--key 'census_data_file
' --part-number<part-number>
--body <file-path> --upload-id "<your-upload-id>" --checksum-algorithm SHA256例如,使用以下命令来上传第二个分段:
aws s3api upload-part --bucket
amzn-s3-demo-bucket1
--key 'census_data_file' --part-number 2 --body census-part01 --upload-id "cNV6KCSNANFZapz1LUGPC5XwUVi1n6yUoIeSP138sNOKPeMhpKQRrbT9k0ePmgoOTCj9K83T4e2Gb5hQvNoNpCKqyb8m3.oyYgQNZD6FNJLBZluOIUyRE.qM5yhDTdhz" --checksum-algorithm SHA256Amazon S3 将在响应的标头中返回每个已上传分段的实体标签(ETag)和额外的校验和。
-
继续使用
upload-part
命令,直到上传了对象的所有分段。
步骤 5:列出分段上传的所有分段
要完成分段上传,您需要列出在这个特定分段上传任务中已经上传的所有分段。list-parts
命令的输出提供了诸如存储桶名称、键、上传 ID、分段编号、eTag、额外的校验和等信息。将此输出保存在文件中会很有帮助,这样您就可以在完成分段上传过程的下一步中使用它。可以使用以下方法创建名为 parts.json
的 JSON 输出文件。
创建列出所有分段的文件
-
要生成包含所有已上传分段详细信息的 JSON 文件,请使用以下
list-parts
命令。将
替换为实际的存储桶名称,并将amzn-s3-demo-bucket1
<your-upload-id>
替换为您在步骤 3 中收到的上传 ID。有关list-parts
命令的更多信息,请参阅《AWS Command Line Interface 用户指南》中的 list-parts。aws s3api list-parts --bucket
amzn-s3-demo-bucket1
--key 'census_data_file
' --upload-id<your-upload-id>
--query '{Parts: Parts[*].{PartNumber: PartNumber, ETag: ETag, ChecksumSHA256: ChecksumSHA256}}' --output json > parts.json这样会生成一个名为
parts.json
的新文件。该文件采用 JSON 格式,包含所有已上传分段的信息。parts.json
文件包含分段上传的每个分段的基本信息,例如分段编号及其相应的 ETag 值,这些是完成分段上传过程所必需的。 -
使用任何文本编辑器或通过终端打开
parts.json
。以下是示例输出:{ "Parts": [ { "PartNumber": 1, "ETag": "\"3c3097f89e2a2fece47ac54b243c9d97\"", "ChecksumSHA256": "fTPVHfyNHdv5VkR4S3EewdyioXECv7JBxN+d4FXYYTw=" }, { "PartNumber": 2, "ETag": "\"03c71cc160261b20ab74f6d2c476b450\"", "ChecksumSHA256": "VDWTa8enjOvULBAO3W2a6C+5/7ZnNjrnLApa1QVc3FE=" }, { "PartNumber": 3, "ETag": "\"81ae0937404429a97967dffa7eb4affb\"", "ChecksumSHA256": "cVVkXehUlzcwrBrXgPIM+EKQXPUvWist8mlUTCs4bg8=" } ] }
步骤 6:完成分段上传
在分段上传的所有分段都上传完毕并且列出分段信息后,最后一步是完成分段上传。此步骤会在 S3 存储桶中将所有上传的分段合并成单个对象。
注意
您可以在调用 complete-multipart-upload
之前,通过在请求中包含 --checksum-sha256
来计算对象的校验和。如果校验和不匹配,Amazon S3 就会让请求失败。有关更多信息,请参阅《AWS Command Line Interface 用户指南》中的 complete-multipart-upload。
完成分段上传
要最终完成分段上传,请使用 complete-multipart-upload
命令。此命令需要用到步骤 5 中创建的 parts.json
文件、存储桶名称以及上传 ID。将 <
替换为存储桶名称,并将 amzn-s3-demo-bucket1
><your-upload-id>
替换为 parts.json
的上传 ID。
aws s3api complete-multipart-upload --multipart-upload file://parts.json --bucket
amzn-s3-demo-bucket1
--key 'census_data_file' --upload-id <your-upload-id>
以下是示例输出:
{ "ServerSideEncryption": "AES256", "Location": "https://
amzn-s3-demo-bucket1
.s3.us-east-2.amazonaws.com/census_data_file", "Bucket": "amzn-s3-demo-bucket1
", "Key": "census_data_file", "ETag": "\"f453c6dccca969c457efdf9b1361e291-3\"", "ChecksumSHA256": "aI8EoktCdotjU8Bq46DrPCxQCGuGcPIhJ51noWs6hvk=-3" }
注意
此时请勿删除各个分段文件。您还需要使用各个分段来对它们执行校验和,从而验证合并在一起的对象的完整性。
步骤 7:确认对象上传到存储桶
完成分段上传后,您可以验证对象已成功地上传到 S3 存储桶。要列出存储桶中的对象并确认新上传的文件已经存在,请使用 list-objects-v2
命令。
列出上传的对象
要列出存储桶中的对象,请使用 list-objects-v2
命令。将
替换为实际存储桶名称:amzn-s3-demo-bucket1
aws s3api list-objects-v2 --bucket
amzn-s3-demo-bucket1
此命令将返回存储桶中对象的列表。在对象列表中查找您上传的文件(例如 census_data_file
)。
有关更多信息,请参阅《AWS Command Line Interface用户指南》中 list-objects-v2
命令的 Examples 部分。
步骤 8:使用 MD5 校验和验证对象完整性
在上传对象时,可以指定校验和算法以供 Amazon S3 使用。默认情况下,Amazon S3 将 MD5 字节摘要存储为对象的 ETag。对于分段上传,ETag 不是完整对象的校验和,而是每个单独分段的校验和组合。
使用 MD5 校验和验证对象完整性
-
要检索已上传对象的 ETag,请执行
head-object
请求:aws s3api head-object --bucket
amzn-s3-demo-bucket1
--keycensus_data_file
以下是示例输出:
{ "AcceptRanges": "bytes", "LastModified": "2024-07-26T19:04:13+00:00", "ContentLength": 16106127360, "ETag": "\"f453c6dccca969c457efdf9b1361e291-3\"", "ContentType": "binary/octet-stream", "ServerSideEncryption": "AES256", "Metadata": {} }
此 etag 的末尾附有“-3”。这表示对象是使用分段上传分为三个分段进行上传的。
-
接下来,使用
md5sum
命令计算每个分段的 MD5 校验和。请确保提供指向分段文件的正确路径:md5sum census-part*
以下是示例输出:
e611693805e812ef37f96c9937605e69 census-part00 63d2d5da159178785bfd6b6a5c635854 census-part01 95b87c7db852451bb38b3b44a4e6d310 census-part02
-
对于此步骤,手动将 MD5 哈希值合并为一个字符串。然后,运行以下命令,将字符串转换为二进制并计算二进制值的 MD5 校验和:
echo "
e611693805e812ef37f96c9937605e6963d2d5da159178785bfd6b6a5c63585495b87c7db852451bb38b3b44a4e6d310
" | xxd -r -p | md5sum以下是示例输出:
f453c6dccca969c457efdf9b1361e291 -
此哈希值应与步骤 1 中原始 ETag 值的哈希值相匹配,这可验证
census_data_file
对象的完整性。
当您指示 Amazon S3 使用其他校验和时,Amazon S3 会计算每个分段的校验和值并存储这些值。如果您想检索仍在进行的分段上传的各个分段的校验和值,可以使用 list-parts
。
有关校验和如何处理分段上传对象的更多信息,请参阅检查对象完整性。
步骤 9:使用额外的校验和验证对象完整性
在本步骤中,教程使用 SHA-256 作为额外的校验和来验证对象完整性。如果您使用了不同的额外校验和,请改用该校验和值。
使用 SHA256 验证对象完整性
-
在终端中运行以下命令(包括
--checksum-mode enabled
参数),以显示对象的ChecksumSHA256
值:aws s3api head-object --bucket
amzn-s3-demo-bucket1
--key census_data_file --checksum-mode enabled以下是示例输出:
{ "AcceptRanges": "bytes", "LastModified": "2024-07-26T19:04:13+00:00", "ContentLength": 16106127360, "ChecksumSHA256": "aI8EoktCdotjU8Bq46DrPCxQCGuGcPIhJ51noWs6hvk=-3", "ETag": "\"f453c6dccca969c457efdf9b1361e291-3\"", "ContentType": "binary/octet-stream", "ServerSideEncryption": "AES256", "Metadata": {} }
-
使用以下命令将各个分段的
ChecksumSHA256
值解码为 base64,然后将其保存到名为outfile
的二进制文件中。这些值可以在parts.json
文件中找到。将示例 base64 字符串替换为实际的ChecksumSHA256
值。echo "
QLl8R4i4+SaJlrl8ZIcutc5TbZtwt2NwB8lTXkd3GH0=
" | base64 --decode >> outfile echo "xCdgs1K5Bm4jWETYw/CmGYr+m6O2DcGfpckx5NVokvE=
" | base64 --decode >> outfile echo "f5wsfsa5bB+yXuwzqG1Bst91uYneqGD3CCidpb54mAo=
" | base64 --decode >> outfile -
运行以下命令计算
outfile
的 SHA256 校验和:sha256sum outfile
以下是示例输出:
688f04a24b42768b6353c06ae3a0eb3c2c50086b8670f221279d67a16b3a86f9 outfile
在下一步中,获取哈希值并将其转换为二进制值。此二进制值应与步骤 1 中的
ChecksumSHA256
值相匹配。 -
将步骤 3 中的 SHA256 校验和转换为二进制,然后将其编码为 base64,来验证它与步骤 1 中的
ChecksumSHA256
值相匹配:echo "688f04a24b42768b6353c06ae3a0eb3c2c50086b8670f221279d67a16b3a86f9" | xxd -r -p | base64
以下是示例输出:
aI8EoktCdotjU8Bq46DrPCxQCGuGcPIhJ51noWs6hvk=
此输出应确认 base64 输出与
head-object
命令输出中的ChecksumSHA256
值相匹配。如果输出与校验和值匹配,则该对象有效。
重要
-
当您指示 Amazon S3 使用额外的校验和时,Amazon S3 会计算每个分段的校验和值并存储这些值。
-
如果您想检索仍在进行的分段上传的各个分段的校验和值,可以使用
list-parts
命令。
步骤 10:清除资源
如果要清理在本教程中创建的文件,请使用以下方法。有关删除上传到 S3 存储桶的文件的说明,请参阅删除 Amazon S3 对象。
删除步骤 1 中创建的本地文件:
要删除您为分段上传创建的文件,请从工作目录中运行以下命令:
rm
census-data.bin
census-part* outfile parts.json