DynamoDB 条件写入是事务性的吗?

Are DynamoDB conditional writes transactional?

我无法理解提供条件写入的 DDB 的二分法,但 最终是一致的。这两个道理似乎自相矛盾。

在经典场景中,用户 Bob 更新密钥 A 并将值设置为“FOO”。用户 Alice 从尚未收到更新的节点读取,因此它获得相同密钥的原始值“BAR”。

如果 Bob 和 Alice 向集群上的不同节点写入数据 ,而没有 条件检查,则可能会发生冲突,Alice 和 Bob 同时向同一密钥写入数据,而 DDB 不会知道哪个更新应该是最新的。此冲突必须由客户端在下次读取时解决。

但是当条件写入使用时呢?

如果 A 的现有值为“BAR”,则用户 Bob 将其对 A 的更新发送为“FOO”。 如果 A 的现有值为“BAR”,则用户 Alice 将 A 的更新发送为“BAZ”。

本地每个节点都可以检查它们的节点是否具有原始“BAR”值并进行更新。但是,要想跨集群了解 A 的真实状态,唯一的方法是首先跨集群进行强一致性读取。这种强一致性读取必须阻塞 Alice 或 Bob,或者他们可以同时进行强一致性读取。

所以这就是我对 DDB 条件写入的性质感到困惑的地方。在我看来,要么:

  1. 条件写入仅在本地评估。合并冲突仍然会发生。
  2. 条件写入是跨集群评估的。

如果它是 #2,我认为可行的唯一方法是:

  1. 为密钥创建了一个锁。
  2. 进行强一致性读取。

假设它是#2。现在这会将 Bob 的更新留在哪里?更新是对节点 2 进行的,并发送到节点 1,我们有多数法定人数。但是为了让 Alice 在进行自己的条件写入时可以使用这些更新,需要从 WAL 中刷新这些更新。那么在条件写入中更新是否总是刷新?通常写入总是刷新吗?

SO 上还有其他类似的问题,但答案是关于此的 AWS 文档的重复或 link。 AWS 文档并没有真正解释这一点(或者我错过了)。

DynamoDB 条件写入是“事务性”写入,但它们的完成方式不是 public 信息,并且可能是专有知识 属性.

DynamoDB 开发人员是唯一知道此信息的人。


你的问题是你是从节点的角度来看这个问题的——我已经看过 every mention of node anywhere in DynamoDB documentation & 它只是提到了 Node.js 或 DAX 节点不是数据库节点

虽然可能有过时的读取 - 是的,这表明某种形式的 node - 没有 database nodes 这样的时候进行条件写入。

User Bob sends their update for A as "FOO" if the existing value for A is "BAR". User Alice sends their update for A as "BAZ" if the existing value for A is "BAR".

谁的请求先到,谁就先通过。

下一次请求将失败,这意味着您现在需要发出新的读取请求以获取最新值,然后继续进行第二次写入。

Amazon DynamoDB developer guide 非常清楚地说明了这一点。

请注意,没有 nodesreplicas 等 - 只有 1 个引用 DynamoDB table:


条件写入是可能评估的跨集群&强一致性读取是可能但亚马逊没有提供此信息public.

Ermiya Eskandary 是正确的,DynamoDB 实施的确切细节不是 public 知识,并且在保留 API 的记录保证的同时,将来可能会发生变化。尽管如此,亚马逊开发人员过去所做的各种文档,尤其是视频演示,已经相对清楚地说明了它是如何在幕后工作的——至少是粗略的,我将在这里尝试解释我的理解: 请注意,这可能不是 100% 准确,而且我对 DynamoDB 没有任何内部知识。

  1. DynamoDB 保留每个项目的三个副本。
  2. 持有特定项目副本的节点之一被指定为该项目的 领导者 (没有单一的“领导者” - 它可以是不同的领导者每件)。据我所知,我们没有详细说明使用哪个协议来选择这个领导者(当然,如果节点宕机,领导者选择会改变)。
  3. A write 到一个项目是在领导者上启动的,领导者序列化对同一项目的写入。请注意 DynamoDB 条件更新如何只能读取和更新 same 项目,因此同一节点(领导者)可以仅使用本地锁读取和写入项目。在 leader 评估代码并决定写入后,它还会向其他两个节点发送更新 - 只有在三个节点中的两个成功写入数据后才向用户返回成功(以确保持久性)。
  4. 您可能知道,DyanamoDB 读取有两个选项 consistenteventually-consistenteventually-consistent read 从三个副本之一随机读取,并且可能还没有看到成功写入的结果(如果写入写入了两个副本,但还没有写入第三个副本)。 consistent 读取从 leader 读取,因此保证读取先前写入的数据。

最后您询问了 DynamoDB 更新且更昂贵的“事务”支持。这是一个完全不同的功能。 DynamoDB“交易”都是关于在同一个请求中对多个项目的读写。正如我在上面解释的那样,旧的条件更新功能只允许读-修改-写操作一次涉及 单个项目 ,因此实现更简单 - 其中单个节点(领导者)可以序列化并发写入并在没有复杂的分布式算法的情况下做出决定(但是,需要复杂的分布式算法来选择领导者)。