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

Can I use a client constructed session token for cosmosdb?

我对在 cosmosdb 的 dotnet v3 sdk 中使用会话令牌做了一些研究,到目前为止,我发现这两个链接为我提供了一些关于如何使用它的提示:utilize-session-tokens and how-to-convert-session-token

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

但是,上面的链接仅显示了如何重用从创建文档返回的令牌。我想知道我是否可以构建自己的会话令牌并将其用于强一致性。

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

提前致谢!

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

要获得in-region强一致性,或者更准确地说,读你自己的写会话一致性提供的保证并且是使用 Cosmos 客户端的单个实例,您已经可以读取您自己的写入保证。您不需要管理会话令牌。 Cosmos SDK 为您代劳。

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

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

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