如何使用有条件写入来防止对象覆盖
通过有条件写入,可以向写入请求中添加一个额外的标头,以便向 S3 操作指定前提条件。这可以通过验证存储桶中尚不存在具有相同键名称的现有对象,来防止覆盖现有数据。有条件写入适用于针对通用存储桶和目录存储桶的 API 请求。
在将对象上传到 Amazon S3 时,请指定键名称。键名称是存储桶中对象的唯一且区分大小写的标识符。如果您在未受版本控制或已暂停版本控制的存储桶中上传具有相同键名称的对象,则该对象将被覆盖。在受版本控制的存储桶中,最近上传的对象将成为对象的当前版本。
有条件写入将在 WRITE
操作期间检查对象是否存在。如果在存储桶中找到相同的键名称,则 WRITE
操作将失败。使用有条件写入,可以让多个客户端写入同一个存储桶,而不会覆盖现有对象。
要执行有条件写入,您必须拥有 s3:PutObject
权限。此权限使调用方能够检查存储桶中是否存在对象。可以在 AWS SDK 中使用带有预签名 URL 的有条件写入。
注意
要使用有条件写入,必须通过 HTTPS(TLS)发出请求,或使用 AWS 签名版本 4 对请求进行签名。
支持的 API
以下 S3 API 支持使用有条件写入:
可以使用以下标头来写入依赖于对象键名称的对象。有关对象键名称的信息,请参阅为 Amazon S3 对象命名。
PutObject
-
If-None-Match
— 仅当指定存储桶中不存在具有相同键名称的现有对象时,才上传对象。必须对此参数使用 *(星号)值。
以下 put-object
示例命令说明了如何使用 AWS CLI,通过 if-none-match
参数借助有条件写入标头上传对象。
aws s3api put-object --bucket
amzn-s3-demo-bucket
--key dir-1/my_images.tar.bz2 --body my_images.tar.bz2 --if-none-match "*"
有关更多信息,请参阅 AWS CLI 命令参考 中的 put-object
有关 AWS CLI 的更多信息,请参阅《AWS Command Line Interface 用户指南》中的什么是 AWS Command Line Interface?。
有关此标头的更多信息,请参阅《Amazon Simple Storage Service API 参考》中的 PutObject。
CompleteMultipartUpload
-
If-None-Match
— 仅当指定存储桶中不存在具有相同键名称的现有对象时,才完成上传。必须对此参数使用 *(星号)值。
以下 complete-multipart-upload
示例命令说明了如何使用 AWS CLI,通过 if-none-match
参数借助有条件写入标头完成分段上传。
aws s3api complete-multipart-upload --multipart-upload file://mpustruct --bucket
amzn-s3-demo-bucket
--key dir-1/my_images.tar.bz2 --upload-iduploadID
--if-none-match "*"
有关更多信息,请参阅 AWS CLI 命令参考 中的 complete-multipart-upload。
有关 AWS CLI 的更多信息,请参阅《AWS Command Line Interface 用户指南》中的什么是 AWS Command Line Interface?。
有关此标头的更多信息,请参阅《Amazon Simple Storage Service API 参考》中的 CompleteMultipartUpload。
有条件写入行为
有条件写入会针对存储桶中的现有对象进行评估。如果存储桶中不存在具有相同键名称的现有对象,则写入操作将成功并导致 200
响应。如果存在现有对象,则写入操作将失败并导致 412 Precondition Failed
响应。对于启用了版本控制的存储桶,作为有条件评估的一部分,S3 会检查是否存在同名的当前对象版本。如果当前没有同名的对象版本,或者当前对象版本是删除标记,则写入操作将成功。否则,它会导致写入操作失败和 412 Precondition Failed
响应。
如果对同一个对象名称进行多个有条件写入,则第一个要完成的写入操作将成功。然后,Amazon S3 使后续写入失败并生成 412 Precondition
Failed
响应。
如果在针对对象的有条件写入操作完成之前,对于对象的删除请求获得成功,则在并发请求的情况下也可能收到 409 Conflict
响应。这是因为删除请求优先于更早启动的有条件写入操作。将有条件写入与 PutObject
结合使用时,可能会在收到 409
错误后重试上传。使用 CompleteMultipartUpload
时,必须使用 CreateMultipartUpload
重新启动分段上传,以便在收到 409
错误后再次上传对象。
考虑以下场景,即两个客户端对同一个存储桶运行操作。
412 前提条件失败响应
有条件写入不考虑任何正在进行的分段上传请求,因为这些对象还不是完全写入的对象。请考虑以下示例,其中客户端 1 正在使用分段上传来上传对象。在分段上传期间,客户端 2 能够通过有条件写入操作成功写入相同的对象。随后,当客户端 1 尝试使用有条件写入完成分段上传时,上传将失败,因为对象已经存在。
409 冲突响应
如果在有条件写入请求可以完成之前,删除请求获得成功,则 Amazon S3 为写入操作返回 409 Conflict
响应。这是因为更早启动的删除请求优先于有条件写入操作。考虑以下示例,其中存储桶中存在文件 puppy.txt
。客户端 1 开始对另一个同样名为 puppy.txt
的文件进行分段上传,目的是通过有条件写入来完成分段上传。在上传过程中,客户端 2 从存储桶中删除 puppy.txt
。当客户端 1 尝试通过有条件写入使用 CompleteMultipartUpload
来上传其自己的 puppy.txt
文件时,它将失败并导致 409
Conflict
响应。在这种情况下,您必须启动新的分段上传。
注意
为了最大程度地降低存储成本,我们建议您配置生命周期规则,以便使用 AbortIncompleteMultipartUpload
操作在指定的天数后删除未完成的分段上传。有关创建生命周期规则以删除未完成的分段上传的更多信息,请参阅配置存储桶生命周期配置以删除未完成的分段上传。