如何确保我的 get 查询不会受到 COSMOS db 中长时间运行的更新的影响?

Posted

技术标签:

【中文标题】如何确保我的 get 查询不会受到 COSMOS db 中长时间运行的更新的影响?【英文标题】:How can I ensure my get query won't be affect by a long running update in COSMOS db? 【发布时间】:2021-12-30 10:26:43 【问题描述】:

我的容器有一组更新需要 10 秒以上(我最终会提高我的 RU 并希望这次能改进)。

我的问题是,我发现如果我在 10 秒以上的更新期间运行 GET,我的检索集将包含一些更新的记录和一些尚未更新的记录。

如何确保我的 GET 不会检索到一组更新一半的数据?

几行思路:

运行 2 次查询并比较所有结果的 e_tag 并确保没有发生更新(即 e_tag 没有更改任何记录),但这感觉像是一个非常大(RU 昂贵)的 hack。 确保我的更新作为单个事务运行(在 COSMOS 中这是如何通过 SPROC 完成的?)并锁定任何GETS(但 COSMOS 不执行锁定,对吗?)

有没有更好的解决方案我没有看到?

【问题讨论】:

您使用什么一致性级别?你看过各种一致性模型吗?您可能必须更改您正在使用的那个,才能适当地处理这个问题。 我可能是错的@DavidMakogon,但一致性级别可以处理跨区域/区域的容器一致性,这不是我要处理的问题。什么也可以解决这个问题(以某种方式,如果可能的话?)将我的写入/更新批处理到单个事务中(因为我认为我的 Promise.all 将有 n 个事务,其中 n 是我的更新/写入数做) 不一定。看看 Session 一致性,例如,如果使用单个写入器会话,则可以保证一致性。除此之外:在您的问题中,没有太多细节可以继续;我建议编辑以给出你正在做什么的具体例子。 【参考方案1】:

我将写入(createDocument / replaceDocument - 有趣的是我无法让 upsertDocument 工作)移动到存储过程中,这对性能非常有用(快 3 倍),

但是,在这些存储过程运行更新期间触发“GET”仍会导致数据集半更新

所以我也将“GET”移到了存储过程中,然后宾果游戏!如果更新正在进行中,存储过程“GET”现在将返回更新开始之前的数据

来自docs:

存储过程和触发器始终在 Azure Cosmos 容器的主副本上执行。此功能可确保从存储过程中读取提供强一致性

【讨论】:

以上是关于如何确保我的 get 查询不会受到 COSMOS db 中长时间运行的更新的影响?的主要内容,如果未能解决你的问题,请参考以下文章

如何为此查询优化 Azure Cosmos 索引

OData 和 Cosmos DB

Azure Cosmos DB 如何按一系列值进行分组

如何在 Azure Cosmos DB 的一个查询中选择多个聚合值

如何使用 LINQ 针对 Azure Cosmos Document DB SQL API 有效地进行动态查询?

Azure 函数:如何将 http 触发器函数的查询字符串参数绑定到 Cosmos DB 的 SQL 查询