首页 > 解决方案 > DynamoDB 是否保证在快速更新时收敛到最新数据?

问题描述

很明显,Dynamo 在并行运行更新/删除时不是线程安全的(除非使用乐观更新锁定或条件写入)。

我想知道的是,在一个接一个地运行更新而没有任何顺序暂停时是否存在一致性问题的风险,如下所示(Javascript):

await dynamo
  .put({ // PUT creates a record if it doesn't exist
    TableName: "table-name",
    Item: {
      id,
      value: "some value"
    }
  })
  .promise();
await dynamo
  .delete({
    TableName: "table-name",
    Key: {
      id
    }
  })
  .promise();

// wait for X seconds for eventual consistency here
const result = await dynamo
  .get({
    TableName: "table-name",
    Key: {
      id
    }
  })
  .promise();
if (result.Item) {
  throw new Error('Oh no, record should have been deleted!');
}

我已经运行了这段代码 1000 次,结果表明在这种情况下可以依靠 Dynamo 来按预期运行(最后更新/删除获胜),但我想确定(文档的链接?)。

更新:换句话说,我想知道当更新发生得很快时,Dynamo 是否保证遵守我发送更新的顺序。

标签: databaseamazon-dynamodbeventual-consistency

解决方案


得到 AWS 支持的回复:

简而言之,是的。无论更新发生得有多快,最新的更新都会“获胜”。您不会遇到 DynamoDB 服务认为数据一致但不一致的情况,从而导致长期陈旧状态。DynamoDB(PutItem、UpdateItem、DeleteItem)的所有“写入”类型命令(返回 HTTP 200 成功代码)均按顺序处理。

如果我正确理解了您在 StackOverflow 上的示例,则您正在放置一个项目,然后立即将其删除。以该顺序运行时,该项目将始终被删除。永远不会出现 PutItem 在 DeleteItem 之前发生得太近的情况,然后您最终会得到未按预期删除的项目。只有在读取数据时才需要关注最终一致性与强一致性 [1]。


您可能知道,从 DynamoDB 表中读取项目有两种不同的方法,最终一致(默认)和强一致。

[+] 最终一致性读取是一半的成本(例如,4 KB 项目的 0.5 RCU)但如果该项目在读取前几秒钟内更新,则可能会返回陈旧数据。[+] 强一致性读取是完全成本的(例如 1 个 RCU 用于 4 KB 项目),可能会导致稍高的网络延迟,并会导致以下结果:

  1. HTTP 200 - 如果项目存在则返回该项目,如果不存在则返回 null。无论 LAST Put/Update/Delete 在读取之前多久运行一次,都是如此。
  2. HTTP 500 - 我们端发生内部网络错误,您需要再次尝试读取(这种情况很少见)您不会看到返回的是陈旧数据或最近删除的项目。

推荐阅读