DynamoDB 如何同时实现高可用性和最终一致性?

How can DynamoDB be HA and eventually consistent at the same time?

我正在阅读 AWS DynamoDB's versioning best practices 但不理解某些内容:

DynamoDB 如何同时做到 HA 最终一致?!

我对设置的理解是:

  1. 在您的数据中(至少)维护一个 version
  2. 插入新记录时,将其作为版本 0(“v0”)插入
  3. 每次您想对该记录进行更改时,您都会插入一个新的(增加的)版本,然后将相同的更改也应用到 v0
  4. 所有读取均针对 v0(最新的最新版本)

但是,当 DynamoDB 标榜为最终一致的数据库时,我不明白它如何强制执行更新条件!有没有人有过实施这些的经验guidelines/practices?

DynamoDB不仅仅是“最终一致”,它其实还有一个强一致性的概念,described here:

When you request a strongly consistent read, DynamoDB returns a response with the most up-to-date data, reflecting the updates from all prior write operations that were successful.

此外,当更新还涉及读取时 - 由于 UpdateExpresionConditionExpression - 此读取也始终以高度一致的方式完成。

但不仅如此...仅强一致性读取不会帮助您允许对版本进行并发更新。您需要的是使用 乐观锁定 等技术来允许并发写入新版本:

  1. 读取(GetItem)项目的当前值(在 v0 中)。最终一致就好了。
  2. 在此项中我们找到当前版本号,比如 7。
  3. 为 v0 写入 (UpdateItem) 一个新值,版本号为 8(我们读取的 7 之后的一个),使用版本 = 7 的 ConditionExpression。如果此条件失败 (ConditionalCheckFailedException),转到 1.
  4. 如果条件成功,则此客户端设置版本8成功,将是唯一个成功设置版本8的客户端。所以我们发送另一个UpdateItem 并设置单独的 v8 项。

此技术存在客户端可能在步骤 3 和 4 之间死亡的风险,并且 v8 的条目将丢失,尽管 v0 中的条目将是新的。但是,当您尝试在两个不同的项目中设置相同的数据时,这总是存在风险 - 一个写入可能成功而另一个将失败 - 解决此问题的唯一方法是使用 transactions 的新 DynamoDB 功能。

虽然其他答案中有一些很好的信息,但我认为它不能完全回答您的问题

How can DynamoDB be HA and eventually consistent at the same time?

答案很简单,DDB 分区是 3 路复制的...

如果你看过AWS Dynamo Deep Dive video,强烈推荐。

因此,当您写入 DDB 时,它会将写入传递给所有三个副本,并在三个写入中的两个成功后 returns 将成功传递给您。

对 DDB 的最终一致性读取也会将读取传递给所有三个副本,并 returns 将它收到的第一个响应传递给调用者。

所以有可能写入成功到两个副本,并且仍然在另一个副本上挂起;并且最终一致读取 returns 来自过时副本的数据。

显然,拥有三个副本可为您提供高可用性。