问题描述
我构建了一个API#1,该API在DynamoDB中创建了一个项目。我正在构建另一个使用GSI检索项目的API#2(输入键可能不存在)。但是GSI的读取最终只能保持一致,我不希望API#1创建一个项目但API#2没有获得该项目的情况。
所以我正在考虑:
- API#1通过UpdateItem创建项目
- API#1尝试使用GSI通过GetItem检索项目。继续以指数退避重试,直到获得该项目为止。一旦发生这种情况,最终的一致性就应该结束了。
- API#2通过GetItem使用与上述相同的GSI检索项目。由于API#1已经获得该商品,因此应该在第一次尝试时就获得该商品。
注意:我不认为API#2可以重试GetItem,因为它的输入键可能永远不存在。
这项工作吗?有更好的解决方案吗?
解决方法
您要查找的属性在文献中被称为单调读取一致性-它是最终的一致性(足够的时间后,您将始终读取新值),但是另外-当您读取新属性时值一次,进一步读取将不会返回较早的值。
我找不到(并且我试图努力地寻找...)任何文档来保证DynamoDB最终一致的读取具有单调的读取一致性。根据我在DynamoDB的实现上看到的演示(我没有任何内在知识),我相信它实际上没有具有单调的读取一致性:
根据我在这些演示文稿中所了解的内容,DynamoDB将每个数据保存在三个节点上。这三个节点之一是“领导者”(针对此数据),并对其进行写操作-一致性读取也是如此。但是最终一致的读取将随机到达三个节点之一。因此,以下情况是可能的:
- 写操作应该在三个节点(X,Y和Z)上更新GSI的三个副本,但目前只更新了X和Y,而Z尚未更新。
- API 1从GSI读取并随机询问节点X并获取新值。
- 现在,API 2从GSI读取。它随机获取节点Z,并获取旧值!
因此,在您的应用程序找到新值之后,另一次读取可能找不到它:-(
如果除了我的“我从演讲中了解的内容”之外,还有其他人可以找到更好的文档,那么我也希望阅读他们的回答。