5

这可能看起来像一个非常基本的问题,但如果我从S3下载文件而另一个进程正在更新文件,是否需要担心要获取不完整的文件?从文件更新时从AWS S3下载

示例:一个200MB的CSV文件。用户A开始用1Mbps的200MB新内容更新文件。 16秒后,用户B开始以200Mbps下载文件。用户B是否获得了原始文件的全部200MB,或者用户B是否获得了〜2MB的用户A的更改而没有其他内容?

回答

9

用户B获取全部200MB的原始文件。

原因是:在S3

PUT操作都是原子。技术上没有“修改”一个对象的东西。当一个对象被覆盖时实际发生的事情是该对象被替换为,而另一个对象具有相同的密钥。但是,直到新的(覆盖)对象完整地上传并且成功地,原始对象才会被实际替换......即使这样,被覆盖的对象在技术上也没有“消失” - 它只被替换为存储桶的索引,以便将来的请求将服务于新对象。 (新服务对象实际上被记录为不能保证总是立即发生,与上传新对象(立即可供下载)相反,覆盖现有对象最终是一致的,这意味着它是可能的 - 但是不太可能 - 在您上传一个对象后很短的时间内,旧副本仍然可以用于后续请求)。

但是,当您覆盖一个对象,并且桶上未启用版本控制时,尽管密钥相同,但旧对象和新对象实际上是独立存储在S3中的。旧对象现在不再被存储桶的索引引用,因此您不再为存储它而收取费用,它很快就会从S3的后备存储中清除。它实际上没有记录多久后发生这种情况......但是(tl; dr)覆盖当前正在下载的对象应该不会引起任何意想不到的副作用。

更新到单个键是原子的。例如,如果您将PUT添加到现有密钥,则后续读取可能会返回旧数据或更新数据,但不会写入损坏或部分数据。

http://docs.aws.amazon.com/AmazonS3/latest/dev/Introduction.html#ConsistencyModel

+0

你能引用源? – PhilT

+2

@PhilT完成。如果“后续”读取可能会返回新旧对象,则可以推断正在进行的下载将继续返回旧对象。当您“覆盖”一个对象时,只有允许S3的前端从存储中获取对象的索引记录被覆盖。新对象分开编写,索引更新,然后清除旧对象(除非启用桶版本控制,在这种情况下,它也会保留)。因此,覆盖是逻辑的,而不是物理的,索引中的短暂复制延迟是最终一致性的原因。 –

+0

完美!谢谢。 – PhilT