【问题标题】:Concurrency in Amazon S3Amazon S3 中的并发性
【发布时间】:2011-06-08 09:27:37
【问题描述】:

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

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

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

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

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

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

【问题讨论】:

    标签: c# concurrency locking amazon-s3 distributed


    【解决方案1】:

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

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

    【讨论】:

    • 我喜欢这个主意!它适用于写入,因为 S3 现在具有写入后读取的一致性,但我想我们仍然冒着不删除对象的风险,因为它不具有删除后读取的一致性。
    【解决方案2】:

    补充一下 amadeus 所说的,如果您的需求不是关系型的,您甚至可以使用 AWS 的 SimpleDB,而且要便宜得多。

    【讨论】:

    • 谢谢,但是我们对象的大小(几个 MB/对象)使 SimpleDB 成为一个非常昂贵(甚至不可能)的选择。
    【解决方案3】:

    我没有使用过 Amazon S3,但这是我的持久性无知的建议。

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

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

    3. 我会做一个专门的服务(如 WCF),其中包含一个并发请求队列。每次您需要删除一个对象时,您都会将一个项目排入队列。该服务将按照自己的节奏将项目出列,并将您的所有 5 个步骤作为单个事务执行。这可能会引入一些延迟,但如果系统读取繁重,则可能看不到这些延迟。

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

    【讨论】:

    • 谢谢!是的,使用某种排队是解决它的一种方法(例如使用 SQS)。但是,我也必须使用它进行写入,而不仅仅是删除(否则一些添加的节点可能会丢失)。我对此的担忧是它可能变得太昂贵(SQS 成为额外成本)或吞吐量不够好。做乐观并发可以解决这个问题。但是,我以前从未实现过类似的东西,所以我有点担心我会引入一些奇怪的错误(因为很难测试并发问题)。
    • @Yrlec,我不知道亚马逊有 SQS。我更多的是考虑 MSMQMass TransitNServiceBus 上的独立 WCF 服务。排队的好处 - 你可以让它单线程排队和多个工人出队(如果可能的话,每个请求都是一个不共享数据的单独的原子操作)。或许你也可以尝试无锁技术来执行需要同步的操作——这仍然是很多问题。
    【解决方案4】:

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

    您可以在 S3 版本控制之上构建并发。 或者让每个referer/node在S3上创建和删除自己的锁资源。 或者使用 Amazon Relational Database Service (RDS)。

    【讨论】:

    • 谢谢,但我们这样做的规模如此之大,以至于我们宁愿避免使用 RDS(可扩展性有限)和 SimpleDB(I/O 成本高)。
    【解决方案5】:

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

    【讨论】:

    • 在这种情况下,您应该在实施中遵守亚马逊服务的性能,否则它可能会成为您链中的瓶颈
    猜你喜欢
    • 2013-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-13
    相关资源
    最近更新 更多