AmazonS3中的并发性

本文关键字:并发 AmazonS3 | 更新日期: 2023-09-27 17:58:43

我目前正在构建一个系统,其中S3将被互联网上的许多计算机用作持久哈希集(S3 URL是根据数据推断的)。如果两个节点存储相同的数据,那么它将使用相同的密钥存储,因此不会存储两次。当一个对象被移除时,我需要知道其他节点是否也在使用该数据。在那种情况下,我不会删除它。

现在,我已经通过添加一个存储节点列表作为写入S3的数据的一部分来实现它。因此,当一个节点存储数据时,会发生以下情况:

  1. 从S3中读取对象
  2. 反序列化对象
  3. 将新节点的id添加到存储节点的列表中
  4. 序列化新对象(要存储的数据和节点列表)
  5. 将序列化的数据写入S3

这创建了一种形式的幂等引用计数。由于互联网上的请求可能非常不可靠,我不想只计算存储节点的数量。这就是为什么我存储一个列表而不是计数器(以防一个节点发送相同的请求>1次)。

只要两个节点不同时写入,这种方法就可以工作。S3(据我所知)没有提供任何方法来锁定对象,从而使所有这5个步骤都成为原子步骤。

您将如何解决这个并发问题?我正在考虑实现某种形式的乐观并发。我应该如何为S3做到这一点?我是否应该使用完全不同的方法?

AmazonS3中的并发性

首先考虑将锁列表与(受保护的)数据分离。创建一个特定于数据的单独存储桶,以包含锁列表(存储桶名称应该是数据对象名称的派生)。使用第二个bucket中的各个文件(每个节点一个,对象名源自节点名)。节点在访问受保护的数据之前将一个新对象添加到第二个存储桶中,节点在访问完后将其对象从第二个数据桶中移除。

这允许您枚举第二个存储桶,以确定您的数据是否被锁定。并允许两个节点同时更新锁列表而不会发生冲突。

为了补充amadeus所说的,如果你的需求不是关系型的,你甚至可以使用AWS的SimpleDB,这要便宜得多。

我还没有使用过AmazonS3,但这是我对持久性无知的建议。

  1. 可以使用命令查询隔离吗?将读取与命令分开会很好,因为此检查只对命令(DELETE)进行,而读取不需要它(如果我正确的话)。

  2. 如果没有对这种同步的本地支持,那么您自己的滚动解决方案可能是高负载方面的瓶颈(可以通过[3]和[4]解决)。所有DELETE都应该通过一个中央位置请求队列。

  3. 我会做一个专门的服务(比如WCF),里面有一个并发请求队列。每次你需要删除一个对象时,你都会把一个项目排队。该服务将按照自己的速度将项目排成队列,并将您的所有5个步骤作为一个事务处理。这可能会引入一些延迟,但是,如果系统读得很重,则这些延迟可能不可见。

  4. 如果系统写得很重,您可能需要添加有助于将请求从队列[3]中出列的工作者

将引用与资源分离可能是个好主意。

您可以在S3版本控制的基础上构建并发性。或者让每个referer/node在S3上创建和删除自己的锁资源。或者使用亚马逊关系数据库服务(RDS)。

您可以在ec2上将自己的锁定机制作为服务来实现,并使用它来同步对S3的访问。在这种情况下,您可以将监视器计数存储在S3中(单独或不单独)