Amazon S3有条件的上传对象

11
我有一个系统,其中我会收到很多消息。每个消息都有一个唯一的ID,但它在其生命周期内也可能接收更新。由于消息发送和处理之间的时间可能非常长(数周),它们被存储在S3中。对于每条消息,只需要最后一个版本。我的问题是偶尔会同时收到两个具有相同ID的消息,但它们有两个版本(旧版和新版)。
是否有一种方式可以在S3中进行有条件的PutObject请求,在其中可以声明“将此对象放置在S3中,除非我已经有一个更新的版本”?

你将如何确定哪个是新的或旧的?你可以插入一个存储时间戳信息的自定义标头,然后检查它以判断其是否较旧/较新。 - datasage
我使用嵌入在每个消息中的时间戳。在每个请求中对S3进行检查会影响性能,并且无法解决竞争条件。我需要一个原子操作。 - David Rabinowitz
3
似乎S3不支持你的使用情况。你能够接近的是版本控制,这意味着两个版本都会被存储。在请求对象时,你需要确定哪个版本才是最新的版本。如果你的对象符合大小限制,一些类似于SimpleDB的东西可能会起作用。 - datasage
2个回答

5

我需要一个原子操作

S3不适用于这种情况,因为它是最终一致性的。以下是一些想法:

  • 您可以尝试对消息进行分区-所有以A-L开头的消息都发送到一个盒子中,M-Z发送到另一个盒子中。然后每个盒子本地检查是否有重复。

  • 您最好的选择可能是某种类型的数据库。根据您的用例,您可以使用常规SQL数据库,或者像Redis这样的简单RAM-only数据库。同时写入多个Redis DB以避免SPOF。

  • SWF可以为每个项目创建一个唯一的处理队列,但这可能意味着比仅在S3中检查更多的HTTP请求。

  • David提出的打开版本控制的想法很有趣。您可以拥有一个守护程序,定期修剪旧版本。在阅读时,您将不得不进行“读取修复”,其中您会搜索版本以寻找最新的对象。


2
这不是关于最终一致性的问题。问题在于S3不支持PUT请求的If-Unmodified-Since或If-Match请求。令人惊讶的是,这些请求对于GET请求是受支持的。请参见https://s3.amazonaws.com/doc/s3-developer-guide/RESTObjectPUT.html和https://s3.amazonaws.com/doc/s3-developer-guide/RESTObjectGET.html。 - jpbochi
1
即使到了2022年末,S3现在已经具备强一致性,但仍然不支持检查和设置样式的操作。 - erik258
如上所述,“读取修复”存在的问题是没有一种一致的方法来确定哪个版本是最新的,哪个是“冲突”的。依赖元数据/时间戳并不可靠,因为它是基于客户端的。在我看来,读取修复是有风险的,并且违反了版本控制的概念,这是关于保护用户数据的。最好的情况下,它可以用于释放一些空间,删除“相同”的ETag版本。 简单地说,如果匹配或未修改自条件将解决此问题,因为它们将防止写入并将信息返回给客户端,然后客户端可以处理这种情况。 - NeverEndingQueue

0

你确定PUT操作可以有基于标签的条件吗? - Ruben Bartelink
2
S3对象标记具有强一致性。更多信息请参见Amazon S3数据一致性模型。 并且使用https://docs.aws.amazon.com/AmazonS3/latest/userguide/amazon-s3-policy-keys.html#getobjectversion-limit-access-to-specific-version-3,您可以使用数字条件策略(如果请求版本大于策略最后更新的版本,则授予Put操作)。 现在问题转移到使用原子条件操作更新策略。 :-( - Fredrik Wendt

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