亚马逊云科技绝大多数新功能都是由客户直接反馈驱动。三年前,亚马逊云科技首席布道师Jeef Barr宣布推出额外的校验和算法,并提供客户端可选的校验和计算服务,以确保存储在Amazon S3上的对象与用户上传对象完全一致。许多用户对此额外验证功能表示了高度认可,因为它让用户确信存储对象即是上传对象。同时,用户也反馈希望这一额外验证功能能够自动启用,以便减轻编写额外代码的负担。
近期,亚马逊云科技更新了Amazon S3在用户上传对象时的默认操作,在保持其现有持久性优势的基础上,Amazon S3还会自动验证数据是否通过网络从应用程序准确传输到Amazon S3存储桶。
Amazon S3数据耐用性高达99.999999999%。当对象到达服务器时,Amazon S3便会通过计算校验和来验证对象上传的完整性,确认无误后再写入多个存储设备。如果您的数据存储在Amazon S3中,它就会通过定期对静态数据进行完整性检查,来持续监控数据耐用性。Amazon S3还会主动监控数据的冗余性,以帮助验证您的对象是否能够承受多个存储设备同时发生故障的情况。
但数据在到达服务器之前会穿越公共互联网,因此仍可能面临完整性风险。在未管理的网络上出现的硬件故障或客户端软件错误等问题,都有可能会在Amazon S3验证数据之前导致数据破坏或丢失。以往您可以通过在PutObject或UploadPart请求中提供自身预先计算的校验和来扩展完整性保护,但这需要配置工具和应用程序来生成和跟踪校验和,要在所有上传对象到Amazon S3的客户端应用程序中一致实施这一策略,复杂程度可能较高。
新的默认行为建立在现有数据完整性保护的基础上,无需对应用程序进行任何更改。此外,新的校验和存储在对象的元数据中,可随时进行完整性验证。
客户端自动完整性保护
Amazon S3现在默认将数据完整性保护一直延伸至客户端应用程序。亚马逊云科技最新版本的Amazon SDK会自动为每次上传的文件计算基于循环冗余校验(CRC)的校验和,并将其发送到Amazon S3。Amazon S3会在服务器端独立计算校验和,并将其与提供的值进行验证,然后再将对象及其校验和持久地存储在对象的元数据中。
如果您的客户端应用程序没有发送CRC校验和,这可能是因为它使用的是Amazon SDK旧版本,或者您尚未更新应用程序自定义代码,此时Amazon S3仍会计算基于CRC的校验和,并将其存储在对象元数据中,以供将来参考。您可以将存储的CRC与您计算的CRC进行比较,验证网络传输是否正确。
这项新功能可让您从最新版本的Amazon SDK、Amazon CLI和亚马逊云科技管理控制台,自动计算和验证新上传的校验和,您还可以随时验证对象元数据中存储的校验和。新的默认数据完整性保护使用现有的CRC32和CRC32C算法或新的CRC64NVME算法。Amazon S3还为开发者提供了跨单个部分和多个部分上传的一致的全对象校验和。
进行多部分文件上传时,Amazon SDK会计算每个部分的校验和。Amazon S3通过UploadPart API,使用这些校验和来验证每个部分的完整性。此外调用CompleteMultipartUpload API时,Amazon S3还会验证整个文件的大小和校验和。
CreateMultiPartUpload API引入了一个新的HTTP标头x-amz-checksum-type,支持您指定要使用的校验和类型。您可以选择全对象校验和(通过组合所有单个部分的校验和计算)或复合校验和。
全对象校验和会与对象元数据一起存储,以供将来参考,这种新的保护机制可与服务器端加密无缝配合。在上传、多部分上传、下载和加密模式中的一致行为简化了客户端完整性检查。使用全对象校验和来验证完整性并将其存储起来以供日后使用的功能,可帮助您简化应用程序。
实操展示
要开始使用这种额外的完整性保护,请更新到最新版本的Amazon SDK或Amazon CLI,启用新的完整性保护无需更改代码。
示例1
当对象在没有校验和的情况下上传时,
Amazon S3会在服务器端为对象附加校验和
本演示编写了一个简单的Python脚本,用于向Amazon S3存储桶上传和下载内容。启用最大日志详细程度,以查看从Amazon S3发送和接收的实际HTTP标头。
import boto3
import logging
BUCKET_NAME="aws-news-blog-20241111"
CONTENT='Hello World!'
OBJECT_NAME='test.txt'
# Enable debug logging for boto3 and botocore to stdout (this is verbose !!!)
logging.basicConfig(level=logging.DEBUG)
# create a s3 client
client = boto3.client('s3')
# put an object
client.put_object(Bucket=BUCKET_NAME, Key=OBJECT_NAME, Body=CONTENT)
# get the object
response = client.get_object(Bucket=BUCKET_NAME, Key=OBJECT_NAME)
print(response['Body'].read().decode('utf-8'))
左右滑动查看完整示意
第一步,本例使用了旧版本的Amazon Python SDK,它不会在客户端计算CRC校验和。尽管如此,仍旧可以观察到Amazon S3在接收到对象后会返回其计算出的校验和。
S3 RESPONSE:
{
...
"x-amz-checksum-crc64nvme": "AuUcyF784aU=",
"x-amz-checksum-type": "FULL_OBJECT",
...
}
左右滑动查看完整示意
示例2
使用手动预计算的CRC64NVME校验和(一种新校验和类型)进行上传
当您无法选择使用最新版本的Amazon SDK时,或者使用自有代码将对象上传到Amazon S3存储桶时,您可以计算校验和并将其包含在PutObject API请求中发送。以下是将内容发送到Amazon S3之前计算校验和的方法,为了保持简洁性,本文使用了新版本Amazon SDK for Python中的checksums包。
from awscrt import checksums
import base64
checksum = checksums.crc64nvme("Hello World!")
checksum_bytes = checksum.to_bytes(8, byteorder='big') # CRC64 is 8 bytes
checksum_base64 = base64.b64encode(checksum_bytes)
print(checksum_base64)
左右滑动查看完整示意
运行后,可以看到CRC64NVME校验和,与上一步Amazon S3返回的校验和相同。
$ python crc.py
b'AuUcyF784aU='
您可在调用PutObject API时,将该校验和作为其中一部分进行提交。
response = s3.put_object(
Bucket=BUCKET_NAME,
Key=OBJECT_NAME,
Body=b'Hello World!',
ChecksumAlgorithm='CRC64NVME', ChecksumCRC64NVME=checksum_base64
)
左右滑动查看完整示意
示例3
新版本Amazon SDK在客户端计算校验和
再次运行上传和下载脚本,本次使用的是最新版本的Amazon Python SDK。Amazon SDK现在会在请求中发送CRC请求头,响应中也包含校验和。您可以轻松比较请求和响应中的版本,以确保接收到的对象正是您上传的对象。
REQUEST:
{
...
"x-amz-checksum-crc64nvme": "AuUcyF784aU=",
"x-amz-checksum-type": "FULL_OBJECT",
...
}
左右滑动查看完整示意
您随时都可以使用HeadObject或GetObject API请求对象校验和,以验证本地副本的完整性。
响应对象包含HTTPHeaders字段中的校验和。
{
...
"x-amz-checksum-crc64nvme": "AuUcyF784aU=",
"x-amz-checksum-type": "FULL_OBJECT",
...
}
左右滑动查看完整示意
示例4
使用基于新CRC的全对象校验和进行多部分上传
使用CreateMultipartUpload、UploadPart和CompleteMultipartUploadAPI上传大规模对象时,最新版本的Amazon SDK将自动为您计算校验和。
如果您想通过已知内容校验和来验证数据的完整性,可以为多部分上传预先计算基于CRC的全对象校验和,以简化客户端工具的使用。在对多部分上传使用全对象校验和时,您在上传对象时无需再跟踪部分级的校验和。
precomputed CRC64NVME checksum for the full object
full_object_crc64_nvme_checksum = 'Naz0uXkYBPM='# start multipart upload
create_response = s3.create_multipart_upload(
Bucket=BUCKET_NAME,
Key=OBJECT_NAME,
ChecksumAlgorithm='CRC64NVME',
ChecksumType='FULL_OBJECT')
upload_id = create_response['UploadId']# Upload parts
uploaded_parts = []# part 1
data_part_1 = b'0' * (5 * 1024 * 1024) # minimum part size
upload_part_response_1 = s3.upload_part(
Body=data_part_1,
Bucket=BUCKET_NAME,
Key=OBJECT_NAME,
PartNumber=1,
UploadId=upload_id,
ChecksumAlgorithm='CRC64NVME')
uploaded_parts.append({'PartNumber': 1, 'ETag': upload_part_response_1['ETag']})# part 2
data_part_2 = b'0' * (5 * 1024 * 1024)
upload_part_response_2 = s3.upload_part(
Body=data_part_2,
Bucket=BUCKET_NAME,
Key=OBJECT_NAME,
PartNumber=2,
UploadId=upload_id,
ChecksumAlgorithm='CRC64NVME')
uploaded_parts.append({'PartNumber': 2, 'ETag': upload_part_response_2['ETag']})# Complete the multipart upload with the FULL_OBJECT CRC64NVME checksum to validate the integrity of your entire object.
complete_response = s3.complete_multipart_upload(
Bucket=BUCKET_NAME,
Key=OBJECT_NAME,
UploadId=upload_id,
ChecksumCRC64NVME=full_object_crc64_nvme_checksum,
ChecksumType='FULL_OBJECT',
MultipartUpload={'Parts': uploaded_parts})print(complete_response)
左右滑动查看完整示意
须知事项
对于现有对象,校验和将在复制其时添加。亚马逊云科技更新了CopyObject API,因此您可以为目标对象选择所需的校验和算法。
这种新的客户端校验和计算已在最新版本的Amazon SDK中实现。当您使用不预先计算校验和的旧版本Amazon SDK或自定义代码时,Amazon S3会对其接收到的所有新对象计算校验和,并将其存储在对象的元数据中,即使对于多部分上传同样如此。
定价和可用性
这一扩展的校验和计算与存储功能可在所有亚马逊云科技区域使用,无需额外费用。
立即更新Amazon SDK和Amazon CLI,以便自动享受为传输数据提供的额外完整性保护。
有关Amazon S3数据完整性保护的更多信息,请参阅Amazon S3用户指南中的检查对象完整性。
Amazon S3用户指南—检查对象完整性:
https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html?trk=4b29643c-e00f-4ab6-ab9c-b1fb47aa1708&sc_channel=el
本篇作者
Sébastien Stormacq
自20世纪80年代中期首次接触Commodore 64以来,Seb专注于软件架构、开发工具以及移动计算领域。他凭借自己的技术热情、干劲、客户至上、好奇心和创造力,激发构建者挖掘亚马逊云科技云服务的价值。
星标不迷路,开发更极速!
关注后记得星标「亚马逊云开发者」
听说,点完下面4个按钮
就不会碰到bug了!
点击阅读原文查看博客!获得更详细内容!