我们知道Amazon S3为大多数操作提供了最终的一致性,但是有不同类型的最终一致性。一种特定形式是单调读取一致性,定义为:
"如果进程已经看到对象的特定值,则任何后续访问都不会返回任何先前的值"
所以,如果我做一个PUT来覆盖一个对象,过了一段时间我得到了新的数据,我保证一旦我看到新的值,后续的GET就不会看到旧值了吗?
答案 0 :(得分:2)
无法保证单调一致性。
在收到最新版本的对象后,您不太可能收到旧版本的对象,但无法保证不可能。当然,接收旧版本的概率接近于0,因为接收旧版本意味着S3中的失败导致索引更新无限期地延迟或丢失。
“索引?”
对象覆盖不会完全覆盖对象。在版本化的存储桶中,新对象被持久存储并且桶索引被更新以添加刚刚上载的对象版本并将其标记为“最新”。这是您在未指定版本ID的情况下请求对象时获得的版本。索引更新的复制被认为是负责最终一致性的机制,因为索引的复制将是读取扩展的明显选择。当您请求之前从未请求过的对象时,会提供对主索引的资源密集型强一致性读取,以确保您永远不会在新对象上获得404。 (这个断言的证明在于记录的警告:当你请求一个不存在的对象时,对象的创建失去了它的直接一致性保证,这意味着索引复制品负面缓存对象不存在的知识,并且这将是一种明智的机制,可以防止对不存在的对象进行过多的强一致索引读取。)
回到覆盖......
单个密钥的更新是原子的。例如,如果您PUT到现有密钥,后续读取可能会返回旧数据或更新数据,但它永远不会写入损坏或部分数据。
https://docs.aws.amazon.com/AmazonS3/latest/dev/Introduction.html
没有任何记录的警告只适用于版本化的存储桶。因此,假设对于未版本化的存储桶,机制是相似的,因为在后备存储中对对象的实际覆盖将使得“它永远不会[读取]损坏或部分数据”<的断言似乎是合理的。 / em>不可能。
当然,一旦你学习了版本化存储桶中对象的version-id,你就可以重复请求该对象的特定版本,并且总是会收到相同的对象,因为对象的新版本总是有一个不同的版本ID。
答案 1 :(得分:0)
研究论文http://www.aifb.kit.edu/images/1/17/How_soon_is_eventual.pdf
已发现约12%的读取违反了单调读取一致性。
遵循的算法是:
- 创建时间戳记
将版本号写入存储系统
连续读取直到旧版本号。不再返回,然后创建一个新的时间戳
- 计算写入时间戳和上次读取时间戳之间的差异
- 重复直到有统计学意义