通过重试GetItem处理读取的最终一致性

问题描述

我构建了一个API#1,该API在DynamoDB中创建了一个项目。我正在构建另一个使用GSI检索项目的API#2(输入键可能不存在)。但是GSI的读取最终只能保持一致,我不希望API#1创建一个项目但API#2没有获得该项目的情况。

所以我正在考虑:

  1. API#1通过UpdateItem创建项目
  2. API#1尝试使用GSI通过GetItem检索项目。继续以指数退避重试,直到获得该项目为止。一旦发生这种情况,最终的一致性就应该结束了。
  3. API#2通过GetItem使用与上述相同的GSI检索项目。由于API#1已经获得该商品,因此应该在第一次尝试时就获得该商品。

注意:我不认为API#2可以重试GetItem,因为它的输入键可能永远不存在。

这项工作吗?有更好的解决方案吗?

解决方法

您要查找的属性在文献中被称为单调读取一致性-它是最终的一致性(足够的时间后,您将始终读取新值),但是另外-当您读取新属性时值一次,进一步读取将不会返回较早的值。

我找不到(并且我试图努力地寻找...)任何文档来保证DynamoDB最终一致的读取具有单调的读取一致性。根据我在DynamoDB的实现上看到的演示(我没有任何内在知识),我相信它实际上没有具有单调的读取一致性:

根据我在这些演示文稿中所了解的内容,DynamoDB将每个数据保存在三个节点上。这三个节点之一是“领导者”(针对此数据),并对其进行写操作-一致性读取也是如此。但是最终一致的读取将随机到达三个节点之一。因此,以下情况是可能的:

  1. 写操作应该在三个节点(X,Y和Z)上更新GSI的三个副本,但目前只更新了X和Y,而Z尚未更新。
  2. API 1从GSI读取并随机询问节点X并获取新值。
  3. 现在,API 2从GSI读取。它随机获取节点Z,并获取旧值!

因此,在您的应用程序找到新值之后,另一次读取可能找不到它:-(

如果除了我的“我从演讲中了解的内容”之外,还有其他人可以找到更好的文档,那么我也希望阅读他们的回答。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...