我可以为 cosmosdb 使用客户端构建的会话令牌吗?

blu*_*oop 5 consistency azure azure-cosmosdb azure-cosmosdb-sqlapi

我已经对在 cosmosdb 的 dotnet v3 sdk 中使用会话令牌进行了一些研究,到目前为止,我发现这两个链接给了我一些关于如何使用它的提示:利用会话令牌如何转换会话-令牌

在我们的场景中,如果更新属于同一个,我们希望具有强一致性(但我们不想对所有数据都使用强一致性)userId,这样当一个实例更新该用户下的数据时,其他人都会立即看到结果。我们还想使用 cosmosdb 作为另一个场景的锁。

但是,上面的链接仅显示如何重用创建文档时返回的令牌。我想知道我是否可以构建自己的会话令牌并使用它来实现强一致性。

例如,如果我想更新特定下的数据,userId我将使用{userId}:-1#1会话令牌。这是使用会话令牌的有效方法吗?我也不确定字段 pkrangeid、Version、GlobalLSN 的含义以及它们在 cosmosdb 处理一致性时扮演什么角色。

提前致谢!

Mar*_*own 5

会话令牌包含客户端无法创建的LSN。会话令牌必须由服务颁发,因为它是为会话一致性提供一致性保证的唯一方法。

为了获得区域内的强一致性,或者更准确地说,读取会话一致性提供的您自己的写入保证,并且使用 Cosmos 客户端的单个实例,您将已经读取您自己的写入保证。您不需要管理会话令牌。Cosmos SDK 会为您做到这一点。

如果您的场景是在不同的进程中拥有多个 Cosmos DB 客户端实例,并且您想要读取自己的写入保证,那么您有两种选择。

  1. 实现有界过时一致性,为该区域中所有 Cosmos 客户端实例的读写提供区域内强一致性。它通过读取两个副本来做到这一点。由于 Cosmos DB 始终写入 3 个副本,因此您可以保证始终读取最新数据,因为 Cosmos DB 将检查两个副本中的 LSN,如果不匹配,则从较高的 LSN 中返回数据。这种方法的优点是非常容易实施。缺点是点读取(即 ReadItemAsync())的成本是从两个副本读取的两倍。

  2. 使用会话一致性并使用持久函数中的有状态实体或类似的东西,这将允许您实现分布式互斥体以跨多个 Cosmos 客户端实例存储和更新会话令牌。这里的优点是点读取仍然是 1 RU,缺点是这种复杂性,而且所有写入都被序列化,因为它们需要根据互斥体对所有写入进行排队,而互斥体需要由每个客户端实例更新。注意:如果您的客户端位于同一进程但位于多个线程上,您可以使用并发集合,它更简单,但仍然需要同步线程,因此在高并发时会影响客户端的写入吞吐量。