我们使用机器学习技术将英文博客翻译为简体中文。您可以点击导航栏中的“中文(简体)”切换到英文版本。
使用 Amazon DynamoDB 处理高并发场景中的条件写入错误
urnValuesOnConditionCheck
Failure 参数允许您按写入尝试失败期间的原样返回项目的副本,从而减少了在想要调查失败原因并重试请求时对读取请求的需求。
alCheckFailedException
只能提供最少的信息,需要额外的读取操作才能了解失败的具体原因。
现在,有了新的
ReturnValuesOnConditionCheckFailur e 参数,你可以选择在响应消息中按失败时的状态
返回商品。此参数在几个用例中可以提供帮助。在这篇文章中,我们将更深入地探讨如何将其与计数器一起使用以提高处理并发更新时的效率。
条件检查概述
具有大量并发更新的环境需要一种机制来确保记录不会因来自多个用户的无序更新而被更改。带有
我们看到在
alCheckFailedException
,要求客户端通过读取项目并重新尝试更新来获取最新版本。这充当验证检查,以确保自获得版本以来该项目没有被其他客户端更改。
现在,为了最大限度地缩短时间并节省
eturnValuesOnConditionCheckFailur e 参数,该参数使 DynamoDB 能够在条件检查失败
时返回项目的状态。此功能使您能够迅速评估状态失败的原因,并就是否继续进行预期更新或更改方法做出明智的决定。
返回值条件检查失败正在运行
想象一下,我们正在对一款电子游戏进行建模,其中有两支队伍,每支队伍有100名玩家并肩竞争。每支队伍都需要制作不同的三明治作为挑战。你生产的三明治越多,挑战出现的速度就越快。有些玩家将成为厨师,而其他大多数玩家将收集制作三明治所需的食材。
因为我们有几位厨师,他们会在制作三明治时消耗食材。当团队没有足够的食材来制作三明治时,游戏需要向团队展示他们缺少什么食物,这样收藏家才能得到它。游戏计算团队分数,因此他们可以与排行榜上的其他队伍竞争,但它还提供个人分数来确定谁是团队中最好的球员。
因为每个玩家都有获得最高分的动力,所以他们倾向于抓住所有三明治订单或获得厨师需要的所有食材。每个三明治都由一个三明治 ID 来识别,这对团队来说是独一无二的,这使得两支队伍无法制作同一个三明治。当一个团队收到确认后,三明治就制作好了,其他厨师就不可能做三明治了。
在我们的烹饪游戏示例中,我们将使用名为 “
GID#
GID#
是表中每个项目的静态前缀,代表 “游戏标识符”。
# ) 符号和代表哈希 (#
) 的二十一个字符的 n
我们还将使用
我们可以使用排序键来实现这种设计模式,其中
TID#
是一个静态前缀,表示与哈希符号和
连接在一起的 “团队标识符”,它也是一个八个字符 nanoid 唯一字符串 (TID#)。
GID#
单表设计方法也允许我们在表中存储其他实体的数据。
TID
# 创建分区键,所有团队成员的信息(我们之前将其用作排序键)也可以成为自己的实体。通过创建
#
SID# 表示 为分区键和排序键,其中 SID#
是静态前缀,表示 “三明治标识符”,与哈希符号和 sand
wich
_id
连接在一起 ,后者是一个八个字符的纳米样唯一字符串。
假设我们是一个扮演厨师角色的玩家,我们正要做一个 BLT 三明治。游戏会告诉我们制作每个三明治需要多少以及需要哪些食材。我们需要首先阅读团队收集的食材,以验证我们是否有使用
GetItem
操作生产三明治所需的食物。下图描绘了游戏作为物品存储在我们的桌子中的示意图,包括我们可用的食材。
这些信息会显示给厨师玩家,但他们仍然需要按下 Make 按钮。这就是并发进入画面的地方。厨师在阅读时很有可能得到相同的信息,但只有第一位厨师才能完成三明治。
在这种情况下,我们需要确保只有在有足够的原料的情况下才能制作三明治。这就是条件更新出现的地方,条件是只有满足条件表达式我们才会更新项目。以下是用于此条件检查的 Python 片段:
使用此代码,当满足条件时,我们会移除三明治所需的食材量,但也会将当前的 sundwich
_
id 添加到
当我们第一次运行这段代码时,我们确实会制作三明治,因为我们的物品含有必需的食材,我们应该会看到如下结果:
我们现在已经做了两个三明治,而且我们已经食用了制作其中一个所需的食材
假设现在我们还有另一位玩家仍然拥有相同的 “读取” 信息,他选择了 Cook 按钮。从我们的剧本角度来看,这意味着他们正在尝试制作同样的三明治。这次,脚本产生了以下错误:
我们知道玩家不符合制作三明治的要求,但是失败的玩家是什么条件呢?我们缺少生菜吗?有人吃了面包吗?还是培根?以前可能有人做过三明治吗?唯一的知道方法是再次发出
GetItem
操作,因为玩家几秒钟前才读取的信息现在已经过时。
随着
ReturnValuesOnConditionCheck
Failure 功能的引入,现在我们可以验证失败的原因,因为我们得到的是存储在 DynamoDB 表中的当前项目的值。在同样的异常逻辑处理中,我们现在可以访问当前项目的值,我们可以检查哪个条件失败了。以下更新的代码片段允许我们查看属性的值:
运行时,我们会看到如下错误,我们可以理解生菜用完了,面包缺了,有人在请求之前做了那个三明治:
得益于这项新功能,应用程序开发人员将节省时间,因为他们不必执行了解当前值所需的额外 GetItem 操作,从而减少了读取操作的次数,还减少了运行此场景所需的应用程序逻辑。
访问控制
根据提供对 亚马逊云科技 资源的最低权限访问权限的 亚马逊云科技 最佳实践,DynamoDB 中的 R
eturnValuesOnConditionCheckFailure 功能遵循相同的方法。
通过聚焦 R
eturn
Values 参数的范围,此功能允许对权限进行精细控制。通过仔细配置与
Return
Values 相关的权限 ,管理员可以选择允许或拒绝 DynamoDB 在条件检查失败时将项目按原样返回。
应用最低权限原则可确保仅向用户和应用程序授予执行所需操作所需的权限。在
ReturnValuesOnConditionCheck
Failure 的背景下,这意味着管理员可以在条件检查失败时限制对项目先前状态的访问,从而提供额外的安全保护并防止未经授权查看敏感数据。
要配置
以下示例 IAM 策略拒绝在特定表的 PutIte
ReturnValuesOnConditionCheck
Failure 的权限 ,管理员可以将 IAM 条件
dynamoDB: ReturnValues 设置为
,或者 将允许将值返回给用户的 ALL_OLD。
无
, 这反过 来意味着它不会返回值
m 或 u pdateItem
上出现条件失败时退回该项目:
其他资源
要成功运行这篇文章中指定的代码,你需要使用 Python SDK 版本 1.26.158。如果你正在使用任何其他 SDK,请记得下载最新的 API 版本,这样你就可以利用 ReturnValuesO
nConditionCheckFailur
e 了。所有编程语言都会将该项目作为异常正文的一部分返回。有关此功能的更多信息,请参阅
结论
通过合并
ReturnValuesOnConditionCheck
Failur e 参数,可以减少额外的读取操作并简化错误处理。现在,当出现 Condition
alCheckFailedException 时,您可以直接从服务器端检
索详细信息,从而提高效率并改进决策。
首先,请将新参数添加到您的 putItem、
你可以在我们的
u pdateItem
或 D
值设置为 ALL_OLD。
eleteItem
操作 中,并将该
作者简介
Esteban Serna
是一名资深的 DynamoDB 专家解决方案架构师。在过去的15年中,Esteban一直在研究数据库,帮助客户选择合适的架构来满足他们的需求。刚从大学毕业的他开始部署支持分布式地点的联络中心所需的基础设施。当引入 NoSQL 数据库时,他爱上了它们,并决定专注于它们,因为集中计算已不再是常态。如今,Esteban 专注于使用 DynamoDB 帮助客户设计需要一位数毫秒延迟的分布式大规模应用程序。有人说他是一本开放的书,他喜欢与他人分享自己的知识。
李·汉尼根
是一名资深的 DynamoDB 专家解决方案架构师。Lee 在过去的 4 年里一直是 DynamoDB 专家,在大数据技术方面有着深厚的背景。凭借与创新型初创公司合作获得的宝贵见解,Lee 为他在欧洲、中东和非洲的 亚马逊云科技 客户带来了丰富的知识。他热衷于帮助 亚马逊云科技 客户扩展其应用程序,他的专长在于使用 DynamoDB 和无服务器技术来实现最佳性能和效率。通过提供量身定制的解决方案和指导,Lee 成功地帮助数百家组织充分发挥 DynamoDB 的潜力并采用无服务器架构。凭借以客户为中心的方法和对 亚马逊云科技 服务的深刻理解,Lee 致力于帮助企业在云计算世界中蓬勃发展。
凯文·威利斯 是
DynamoDB 团队的高级产品经理。他专注于提升开发者体验。凭借在关系 OLTP 系统方面十多年的经验,他热衷于帮助具有类似背景的人快速大规模使用 Amazon DynamoDB。
*前述特定亚马逊云科技生成式人工智能相关的服务仅在亚马逊云科技海外区域可用,亚马逊云科技中国仅为帮助您发展海外业务和/或了解行业前沿技术选择推荐该服务。