当前位置: 首页 > 知识库问答 >
问题:

在 Azure cosmos DB 中维护分布式增量计数器

秋光熙
2023-03-14

我对cosmos DB相当陌生,并试图了解azure cosmos DB SDK为修补文档提供的Java的增量操作。我需要在容器中的一个Documents中维护一个增量计数器。文档看起来像这样-

{"counter": 1}

现在,在我的应用程序中,每当一个动作发生时,我想将这个计数器的值增加1。为此,我使用了宇宙空间运算。我在这里添加了一个增量,就像这样< code > cosmos patch . increment("/counter ",1)工作正常。

现在,此应用程序可以运行多个实例,所有这些实例都与 cosmos 容器中的同一文档通信。因此,App1 和 App2 都可以同时触发增量。SDK 方法返回更新的文档,我需要使用该更新的值。

我的问题是,cosmos DB在这里是否采用了一些锁定机制来确保补丁一个接一个地发生,在这种情况下,我将在App1和App2中获得的更新值是什么(SDK方法返回更新的文档)。其中一个会是2个,另一个中是3个吗?

Couchbase在集群级别支持这样一个计数器,正如这里所解释的,它对我来说工作得非常好,没有任何并发问题。我现在正在迁移到cosmos Db,一直在努力寻找如何实现这一点。

更新1:

我决定测试一下。我在本地mac中设置了cosmos模拟器,并创建了一个DB和容器,其中RU从1到10K自动增加。然后在这个容器中我添加了一个这样的文档-

{
"id": "randomId",
"counter": 0
}

发布这篇文章我创建了一个简单的API,其职责只是在每次调用时将计数器增加1。然后我使用locust多次调用此API来模拟一个类似负载的小场景。最初,测试运行良好,每次调用都会收到一个计数器,就像它应该的那样(以增量方式)。在增加负载时,我看到一些错误,即状态代码为408的Request estTimeOutException。其他请求仍然运行良好,它们获得了正确的计数器值。我不明白是什么导致了这里的Request estTimeOut异常。堆栈跟踪暗示与并发有关,但我无法理解它。这是堆栈跟踪-

更新2:更新1中的测试运行是在我的本地机器上完成的,我意识到我的本地可能有资源问题导致这些错误。决定在Pre-Prod环境中使用实际的cosmos DB而不是模拟器进行测试。

测试配置-

  1. 带有RUs的Cosmos DB容器可自动从400缩放到4000。
  2. 2个应用程序实例共享负载
  3. 用于接收应用程序上的负载的Locust脚本

调查结果-

直到大约170 TPS,一切都运行顺利。除此之外,我注意到属于2个不同桶的错误-

  1. 异常”: “[”请求速率很大。可能需要更多请求单位,因此未进行任何更改。请稍后重试此请求。了解更多: http://aka.ms/cosmosdb-error-429“]”。

我不确定170多个补丁操作将如何耗尽4000个RU,但这是完全不同的讨论。

此错误清楚地表明cosmos DB不处理并发请求。我想了解他们是在内部维护队列来处理某些请求,还是根本不处理任何并发写入。

共有1个答案

柳胜
2023-03-14

PATCH与其他操作没有什么不同,从根本上说,CosmosDB实现了乐观并发控制,这与具有这些机制的关系数据库不同。开放式并发控制 (OCC) 允许您防止丢失更新并保持数据正确。OCC 可以通过使用文档的 etag 来实现。T Azure Cosmos DB 中的每个文档都有一个 E_TAG 属性。

在你的场景中,是的,如果两者都成功,它将在其中一个中返回2,在另一个中返回3,因为SDK具有重试机制,并且在此处进行了说明。另请查看此示例。

如果您的Azure Cosmos DB帐户配置了多个写入区域,则冲突和冲突解决策略适用于文档级别,最后写入成功(LWW)是默认的冲突解决策略

 类似资料:
  • 除了如何有效地参与一个项目的贡献之外,你可能也需要了解如何维护项目。 这包含接受并应用别人使用 format-patch 生成并通过电子邮件发送过来的补丁,或对项目添加的远程版本库分支中的更改进行整合。 但无论是管理版本库,还是帮忙验证、审核收到的补丁,都需要同其他贡献者约定某种长期可持续的工作方式。 在特性分支中工作 如果你想向项目中整合一些新东西,最好将这些尝试局限在特性分支——一种通常用来尝

  • 我试图更好地理解梁计算模型,并检查我的问题是否可以在该模型内解决。 假设我有一系列事件, 我想建立管道: 读取事件流 我读过关于有状态处理的内容,据我所知,在StatefulParDo中维护用户的最大分数很容易。但这种状态是如何存储的是Beam实现的细节,而这种状态在StatefulParDo函数之外是不可用的。 是否有可能在某种可供外部消费者(我的管道之外的读取器)使用的KV存储中以定义良好的格

  • 问题内容: 我有一个生成计数器的要求,该计数器将发送到一些api调用。我的应用程序在多个节点上运行,因此我想如何生成唯一计数器。我尝试了以下代码 并通过Task Parallel libray运行测试。当我有边界值时,我看到的是设置了多次0条目 请让我知道我需要做的更正 更新:我的最终逻辑如下 问题答案: 实际上,您的代码在翻转边界附近并不安全,因为您正在执行“获取”,(等待时间和思考),“设置”

  • 问题内容: 这是我的mysql查询 我想沿着边名选择一个增量计数器。所以预期的输出将是 问题答案: 这部分: 使得可以引入变量而无需单独的查询。因此,第一个查询也可以分为以下两个查询: 例如在存储过程中使用时。

  • 分支维护 你一定注意到了Subversion极度的灵活性,因为它用相同的底层机制(目录拷贝)实现了分支和标签,因为分支和标签是作为普通的文件系统出现,会让人们感到害怕,因为它太灵活了,在这个小节里,我们会提供安排和管理数据的一些建议。 版本库布局 有一些标准的,推荐的组织版本库的方式,许多人创建一个trunk目录来保存开发的“主线”,一个branches目录存放分支拷贝,一个tags目录保存标签拷

  • 大多数成熟的项目都平行的维护多个发布线。例如,1.0.0发布后,该发布线会继续微小发布1.0.1,1.0.2等等,直到项目明确的决定终止这条线。请注意,仅仅因为发布了1.1.0不足以终止1.0.x线。例如,一些用户会制定某类政策,永远不升级到较新的次要或主要版本的第一个发布—他们希望其他人能将bug试验出来,例如1.1.0,那么就等待1.1.1。这不一定是自私(请牢记,他们也放弃了bug修正和新特