就像你已经知道的那样...
问:Amazon S3 采用什么数据一致性模型?
所有区域中的 Amazon S3 存储桶为新对象的 PUTS 提供写入后读取一致性,并为覆盖 PUTS 和 DELETES 提供最终一致性。
— https://aws.amazon.com/s3/faqs/ https://aws.amazon.com/s3/faqs/
...就一致性模型的官方声明而言,这就是全部内容。
然而,我建议可以从这里以合理的确定性推断出其余部分,以及我们可以合理做出的假设,再加上对 S3 内部工作原理的一些额外的一般见解。
例如,我们知道 S3 实际上并未以分层结构存储对象,但是:
Amazon S3 维护每个 AWS 区域中的对象键名称的索引。对象键按字典顺序存储在索引中的多个分区中。
http://docs.aws.amazon.com/AmazonS3/latest/dev/request-rate-perf-considerations.html http://docs.aws.amazon.com/AmazonS3/latest/dev/request-rate-perf-considerations.html
这意味着 S3 至少有两个离散的主要组件:保存数据的后备存储,以及指向后备存储中位置的键索引。我们还知道,两者都分布在多个可用区中,因此两者都会被复制。
后备存储与索引分离的事实并不是一个既定的结论,除非您记住存储类可以基于每个对象进行选择,这几乎必然意味着索引和数据是分开存储的。
从覆盖的事实来看PUT
操作是最终一致的,我们可以得出结论,即使在非版本化存储桶中,覆盖实际上也不是覆盖后备存储,而是覆盖该对象键的索引条目,并最终释放该存储桶。后备存储中不再被索引引用的空间。
我在这些断言中看到的含义是索引被复制,并且覆盖后读取(或删除)可能会命中尚未反映最近覆盖的索引副本......但是当读取时在其本地索引中遇到“没有这样的键”的情况,系统会采用更资源密集的路径来询问“主”索引(无论这在 S3 架构中实际上意味着什么),以查看这样的对象是否确实存在,但本地索引副本根本还没有得知这一点。
自从第一次GET
几乎可以肯定,新对象未复制到适当的本地索引副本的情况很少见,因此可以合理地预期,S3 的架构师允许更高成本的“发现”操作以改善用户体验,当系统中的节点认为这可能是它遇到的情况。
综上所述,我建议您最有可能遇到的行为是:
GET
覆盖后版本化对象上没有 versionIdPUT
将是最终一致的,因为服务读取请求的节点不会遇到“无这样的键”条件,因此不会遵循我上面推测的理论上成本更高的“发现”模型。
GET
明确请求最新的 versionId 将在覆盖时立即保持一致PUT
,因为读取节点很可能会启动高成本策略来获得上游确认其索引是否反映了所有最新数据,当然这里的条件是“No Such Version”,而不是“No Such Key”。
我知道猜测不是你所希望的,但缺乏记录的确认或经验(或者可能是一些really令人信服的轶事)相反的证据,我怀疑这是我们根据有关 S3 平台的公开信息得出的最接近可信的结论。