【问题标题】:ETag availability guarantees for AWS S3 objectsAWS S3 对象的 ETag 可用性保证
【发布时间】:2020-09-26 23:57:50
【问题描述】:

假设我更新了一个现有的 AWS S3 对象。

aws s3 mv dataset.csv s3://my-bucket

然后我立即提交 HEAD 请求以获取 ETag。

aws s3api head-object --bucket my-bucket --key dataset.csv

我是否保证从 HEAD 获得最新的 ETag,或者即使在 aws s3 mv 在本地完成之后,AWS 仍然有可能对对象进行哈希处理?更一般地说,我可以在哪里阅读有关 AWS ETag 时间和可用性保证的信息?

编辑:自定义 ETag

按照以下 cmets 中的建议,我尝试使用 put-object--content-md5 标志提供自己的 ETag,但遇到了错误。

$ md5sum file
d41d8cd98f00b204e9800998ecf8427e  file
$ aws s3api put-object --bucket my-bucket --key file --body a --content-md5 d41d8cd98f00b204e9800998ecf8427e

An error occurred (InvalidDigest) when calling the PutObject operation: The Content-MD5 you specified was invalid.

【问题讨论】:

  • 问题不在于是否更新了电子标签。这是您是否正在访问“更新”对象。见:Amazon S3 data consistency model
  • 所以 ETag 和数据匹配,但它们都可能是陈旧的?我需要做些什么来保证立即的一致性,而不仅仅是最终的一致性?在 PUT 中,有没有办法将 VersionId 或 Metadata 设置为我在本地检查的 UUID?
  • 是的。不,一致性模型是由 S3 定义的。顺便说一句,我认为您假定 ETag 是由 S3 计算的,但实际上您可以放置​​自己的 ETag。所以你可以做的是利用 ETag 来存储你自己的 UUID,然后用它来检查。
  • 自定义 ETag 更适合我的目的。谢谢!
  • 那么我该如何提供 ETag?我尝试了--content-md5 标志,但遇到了错误(上面的新编辑)。

标签: amazon-web-services amazon-s3 aws-cli


【解决方案1】:

我能保证从 HEAD 获得最新的 ETag

如果处理您的请求的 S3 节点已经拥有一个足够新的存储桶索引版本以包含新对象,则HEAD 请求将返回新对象 ETag。

当你覆盖一个对象时,S3 并没有真正覆盖任何东西——它在一个新的内部位置存储一个副本,然后更改它的内部索引记录以指向内部的新对象位置。桶索引会被复制,并且在任何时候,每个内部索引副本都会滞后主索引一段时间,这可以而且通常非常接近于零,但不能保证是。

因此,在索引更新完全传播之前,GETHEAD 都可以返回旧对象或新对象,完全完好无损、永不损坏且永不被部分覆盖。

AWS 是否仍有机会对对象进行哈希处理

相对于主体和元数据(包括 ETag),一切都是原子的且不可变的。您永远不会看到带有旧 ETag 的新对象主体。那里没有可能的延迟时间,因为 S3 实际计算并返回新的 ETag as part of the upload response

如果您每次访问对象时都绝对需要接收新版本,则必须使用新的对象密钥上传对象。这是 S3 做出的唯一即时一致性保证。其他一切都是最终的;但是,ETag 和对象主体不会彼此不同步。

【讨论】:

  • 谢谢!一个后续澄清问题:ETag 上的相同保证是否也适用于元数据?覆盖后,是否有可能拥有新的自定义元数据和旧的正文?似乎它们应该是一致的,但我想更加确定。
  • 是的,它们的元数据和 ETag 的行为方式相同,不,您不能添加元数据...但是,您可以用自身的副本覆盖对象(避免重新上传)并替换具有新元数据的自定义元数据。 (要添加“附加”元数据,您必须提供您想要保留的任何旧元数据。)复制对象操作允许源和目标是相同的存储桶 + 对象键,这就是元数据“更新”的完成方式。
【解决方案2】:

您无法控制 ETag,甚至在上传完成之前都不知道它会是什么。 --content-md5是为了验证对象的上传,但是随后S3会计算出最终的ETag值(ref)。

GET 和 HEAD 请求是先读后写一致的,所以如果你创建一个新对象然后获取它,你总是会得到它。文档没有特别提到 ETag,但它是 GET 的一部分,所以我想它也总是最新的。 (docs)。需要注意的是,这种一致性模型在以下两种情况下不成立:

  • 您覆盖了该对象。在这种情况下,您可能会得到新的或旧的
  • 在上传对象之前发出 HEAD 或 GET。这通常不是问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多