在文件更新时从AWS S3下载

12

这可能看起来是一个非常基础的问题,但如果我在另一个进程更新S3中的文件时下载该文件,我需要担心文件不完整的问题吗?

举个例子:一个200MB的CSV文件。用户A开始以1Mbps的速度更新该文件的200MB新内容。16秒后,用户B以200Mbps的速度开始下载文件。用户B是否会获得原始文件的全部200MB,还是只会获得用户A更改的约2MB内容而已?

1个回答

24

User B获得了原始文件的全部200MB。

原因在于:

S3上的PUT操作是原子性的。技术上讲,不存在“修改”对象的情况。实际上,在覆盖对象时,会用具有相同关键字的新对象替换原对象。但是,在新(覆盖)对象完全上传并成功后,原始对象才真正被替换...即使如此,覆盖的对象还没有从技术上“消失”,它只是在桶的索引中被替换,以便将来的请求将服务于新对象。

(实际上,为新对象提供服务并不保证总是立即发生。与上传新对象不同,覆盖现有对象是“最终一致性”的,这意味着在上传对象后的短时间内,旧副本仍可能为随后的请求提供服务,尽管这种可能性很小)。

但是,当您覆盖一个对象,并且桶上未启用版本控制时,旧对象和新对象实际上在S3中独立存储,尽管具有相同的关键字。旧对象现在不再由桶的索引引用,因此您不再为其存储而计费,它将很快从S3的后备存储中清除。实际上没有记录这会在多久之后发生...但是总之,覆盖当前正在下载的对象不应该引起任何意外的副作用。

对单个密钥的更新是原子的。例如,如果您向现有密钥进行PUT操作,则随后的读取可能返回旧数据或更新的数据,但它永远不会写入损坏或部分数据。

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


你能提供一个参考来源吗? - PhilT
2
@PhilT 完成。如果“后续”读取可能返回新对象或旧对象,则可以推断正在进行的下载将继续返回旧对象。当您“覆盖”对象时,只有允许S3前端从存储中获取对象的索引记录被覆盖。新对象是单独编写的,索引已更新,然后旧对象被清除(除非启用了存储桶版本控制,否则也会保留)。因此,覆盖是逻辑上的而不是物理上的,并且索引中的短暂复制延迟是最终一致性的原因。 - Michael - sqlbot
完美!谢谢。 - PhilT
截至2020年12月,https://aws.amazon.com/blogs/aws/amazon-s3-update-strong-read-after-write-consistency/ 关于最终一致性的评论已不再正确 - 现在所有内容都是强一致性的。 - jeremycg
@jeremycg 这是真的。由于在 re:Invent 2020 上宣布的一些消息,我有许多答案需要注释或更新。 - Michael - sqlbot

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接