为什么我不能获得全局二级索引的一致读取?
我有以下设置:
- 表:
tblUsers
(id为hash) - 全球二级指数:
tblUsersEmailIndex
(email作为hash,id作为attribute) - 全球二级指数:
tblUsersUsernameIndex
(用户名为哈希,ID为属性)
我查询索引以检查给定的电子邮件或用户名是否存在,这样就不会创建重复的用户。
现在,问题是我不能对索引上的查询进行一致的读取。但为什么不呢?这是我真正需要最新数据的少数情况之一。
根据AWS文档:
对全局辅助索引的查询仅支持最终一致性。
在正常情况下,对表数据的更改会在几分之一秒内传播到全局辅助索引。然而,在一些不太可能的故障场景中,可能发生更长的传播延迟。因此,您的应用程序需要预测和处理全局二级索引上的查询返回的结果不是最新的情况。
但我该怎么处理这种情况呢?如何确保给定的电子邮件或用户名不在数据库中?
5条答案
按热度按时间htzpubme1#
你可能已经经历过了:http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GSI.html
简短的回答是,你不能做你想做的事情与全球二级索引(即它总是最终的一致性)。
这里的一个解决方案是将您感兴趣的属性作为一个键,并在那里进行一致的读取。你需要确保你正在更新,每当你插入新的实体,你也必须担心的边缘情况下,插入成功,但不是在主表(即你需要确保他们是同步的)
另一种解决方案是扫描整个表,但如果表很大,那么这可能是多余的。
你为什么要关心有人用同一个电子邮件创建了两个帐户?您可以只使用用户名作为主哈希键,而不强制电子邮件的唯一性。
ar7v8xwq2#
当您尝试使用
putItem
时,您可以使用ConditionExpression
来检查是否满足放置项目的条件,这意味着您可以检查email
或username
是否存在。https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB.html#putItem-property
vmdwslir3#
我最近遇到了这个问题,想分享一个更新。2018年,DynamoDB增加了事务。如果你真的需要保持两个项目(在相同或不同的表中)100%同步,而不需要担心最终的一致性,TransactWriteItems和TransactGetItems就是你所需要的。
最好是完全避免交易,如果可以的话,就像其他人建议的那样。
ncecgwcz4#
你不可能在GSI上有强一致的读数。你能做的是
将您的模式建模为具有2行,e。g:-
kq4fsx7k5#
根据您的情况并考虑所有替代方案,当您第一次在GSI上没有找到任何内容时,添加自动重试可能是可以接受的,以解决缺乏强一致性读取的问题。我甚至没有想到这一点,直到我遇到了其他选项的障碍,然后意识到这很简单,不会对我们的特定用例造成任何问题。
}
由于我们不关心发送不存在的令牌的人的性能(无论如何都不应该发生),因此我们在没有任何性能损失的情况下解决了这个问题(除了在令牌创建后可能有一次1秒的延迟)。如果您刚刚创建了令牌,则不需要将其解析回刚刚传入的数据。但如果你这样做了,我们会以透明的方式处理。