在AWS S3中创建对象的新版本最终是一致的还是写后读一致的?

时间:2016-02-19 17:51:37

标签: amazon-web-services amazon-s3

我从亚马逊的文档中看到,向S3写入一个新对象是写后读一致的,但更新和删除操作最终是一致的。我猜想在打开版本控制的情况下推送对象的 新版本 最终会像更新一样保持一致,但我无法找到任何要确认的文档。有谁知道吗?

编辑:我的问题是关于GET的行为,无论是否指定了显式版本。

我真的很喜欢我项目的 更新 上的写后读写行为,我可能只能模拟插入,但它可能会如果推送新版本的对象提供了所需的行为,则会更容易。

3 个答案:

答案 0 :(得分:2)

如你所知......

  

问:Amazon S3采用什么数据一致性模型?

     

所有Regions中的Amazon S3存储桶为新对象的PUTS提供读写后一致性,并为覆盖PUTS和DELETES提供最终一致性。

     

- https://aws.amazon.com/s3/faqs/

......就所有情况而言,至于一致性模型的官方声明。

但是,我建议其余部分可以从中得出合理的确定性,以及我们可以合理地做出的假设,以及对S3内部运作的一些额外的一般见解。

例如,我们知道S3实际上并没有将对象存储在分层结构中,而是:

  

Amazon S3维护每个AWS区域中的对象键名称索引。对象键以字典方式存储在索引中的多个分区中。

     

http://docs.aws.amazon.com/AmazonS3/latest/dev/request-rate-perf-considerations.html

这意味着S3至少有两个独立的主要组件,一个支持数据的后备存储,以及一个指向后备存储中位置的键索引。我们也知道它们都分布在多个可用区域中,因此它们都被复制。

支持存储与索引分离的事实并不是定论,直到您记住存储类是基于每个对象可选的,这几乎必然意味着索引和数据是分开存储的。

由于覆盖PUT操作最终是一致的,我们可以得出结论,即使在非版本化的存储桶中,覆盖实际上并不是覆盖后备存储,而是覆盖了该对象的密钥的索引条目,以及最终释放后备存储中的空间,该空间不再被索引引用。

我在这些断言中看到的含义是索引被复制,并且读取后覆盖(或删除)可能会触及尚未反映最新覆盖的索引的副本......但是当一个读书遇到一个"没有这样的键"在其本地索引中,系统追求更多的资源密集型路径来询问" master"索引(无论在S3的体系结构中实际意味着什么),看看这样的对象是否确实存在,但是本地索引副本还没有学到它。

由于没有复制到适当的本地索引副本的新对象的第一个GET几乎肯定是罕见的,因此可以合理地预期S3的架构师会以更高的成本获得此容差。 #34;发现"当系统中的节点认为这可能是它遇到的情况时,改善用户体验的操作。

从这一切开始,我建议您将体验到的最可能的行为是:

    在覆盖GET之后,在版本化对象上没有versionId的
  • PUT最终会保持一致,因为服务于读取请求的节点不会遇到No Such Key条件,并且因此,不遵循理论上更高成本的发现"模型我在上面推测。

  • GET对最新版本ID的明确请求将在覆盖PUT上立即保持一致,因为读取节点可能会启动高成本策略以获取上游是否确认它的索引反映了所有最新数据,虽然当然这里的条件是No Such Version,而不是No Such Key。

我知道猜测并不是你所希望的,但缺乏记录确认或经验(或者可能是某些真正令人信服的轶事)相反的证据,我怀疑这是我们最接近的证据根据有关S3平台的公开信息得出可信的结论。

答案 1 :(得分:1)

在启用操作期间指定版本ID始终与启用版本控制的对象保持一致。

答案 2 :(得分:0)

我不会假设任何事情。

我要做的是从PUT请求中捕获versionid(在x-amz-version-id头中返回)并发出GET(甚至更好的HEAD)以确保该对象确实持久存在并且在S3中可见。