可以在 Amazon S3 API 中使用伪“锁定”对象吗?

Azz*_*zip 7 java consistency amazon-s3 amazon-web-services

我正在考虑使用“锁定”S3 对象,以防止对给定 S3 对象同时进行相同的操作。但我对这个技术方案的有效性抱有很大的怀疑。

更准确地说,在对对象进行操作开始时,将创建与对象名称和所执行操作类型相对应的锁定文件。

示例:在 myObject 上的 myOperation 开始时,将查找 lck/myObject/myOperation 对象,如果不存在则创建该对象。

无论操作成功与否,这个“锁定”对象都会在操作结束时被销毁。

我知道标准解决方案是使用数据库,但应用程序目前没有数据库。因此,如果我只能处理与 S3 的一致性,那就足够了。

我担心的是这个锁对象系统将在多线程/可能是多节点架构中运行。现在,我了解到 Amazon S3 支持“写后读一致性”。

这是否意味着,如果我的应用程序 1(节点 1)/线程 2 通过 Java Amazon S3 API 在给定存储桶上放置锁定对象,则该锁定对象将立即对使用相同 API 的其他线程和其他应用程序可见?

mis*_*ner 7

如果您在 2023 年来到这里,仍然认为使用 S3 进行锁是一个好主意,那么由于增强的一致性模型,这可以以保证无竞争条件的方式实现,并且在锁获取期间没有任何强制等待期

  1. 确定锁的基本名称(例如,some-dir/interesting-object.lock
  2. Writer 在存储桶中创建空对象some-dir/interesting-object.lock.<uuid>。可以<uuid>为每个锁生成一次,也可以为每个写入器生成一次(我们假设写入器不会同时写入),这并不重要。
  3. 列出带有前缀的对象some-dir/interesting-object.lock.
  4. 检查带有“我们的”UUID 的文件是否是最旧的ModifiedTime。在两个 s 相等的极不可能的情况下ModifiedTime,根据 UUID 的字典顺序打破平局。
  5. 如果上述检查成功,则您已获得锁。您现在可以做这项工作了。否则,有人会抢先一步。
  6. 删除锁定文件(注意:这意味着如果获取失败,应立即删除锁定文件)。

这是有效的,因为它保证一旦 put 成功,它将立即显示在列表调用中,并且每个工作人员在 put 后​​都会执行列表。如果另一个编写者甚至在我们晚一纳秒写入对象,他们仍然 100% 保证在他们的列表调用中看到我们的对象首先在那里。

为了允许删除陈旧/过期的锁(应在步骤 4 的检查中排除这些锁,并删除文件),这需要对关键部分的持续时间设置上限,尽管可以任意延长锁时间通过创建具有不同 UUID 的新锁定文件(当您可以删除旧锁定文件时会受到一些限制,但我现在懒得考虑这一点)。另外,为了确定锁是否陈旧/过期,不要依赖本地计算机的时间,而是使用ModifiedTime新创建的锁对象的时间作为校准时钟源。

我并不是说在 S3 中使用锁文件是一个好主意,但这并没有改变它是可能的事实。


std*_*bar 4

不,不幸的是它不会。从S3一致性模型来看:

进程将新对象写入 Amazon S3 并立即列出其存储桶中的密钥。在更改完全传播之前,该对象可能不会出现在列表中。

和:

Amazon S3 目前不支持对象锁定。如果同时对同一键发出两个 PUT 请求,则具有最新时间戳的请求获胜。如果这是一个问题,您将需要在应用程序中构建对象锁定机制。

因此,如果您的两个线程或进程都尝试在 S3 中创建锁,它们将被允许,但最后的写入获胜,因此您还没有真正锁定任何内容。需要发生其他事情才能使锁定起作用