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

Azure 我可以为cosmosdb使用客户端构造的会话令牌吗?,azure,azure-cosmosdb,azure-cosmosdb-sqlapi,consistency,Azure,Azure Cosmosdb,Azure Cosmosdb Sqlapi,Consistency,我对cosmosdb的dotnet v3 sdk中使用会话令牌做了一些研究,到目前为止,我发现了以下两个链接,它们为我提供了一些如何使用会话令牌的提示:和 在我们的场景中,如果更新属于同一个userId,我们希望具有强一致性(但不希望对所有数据使用强一致性),这样当一个实例更新该用户下的数据时,其他所有人都将立即看到结果。 我们还希望使用cosmosdb作为另一个场景的锁 但是,上面的链接仅显示如何重用创建文档时返回的令牌。我想知道我是否可以构造自己的会话令牌并使用它来实现强一致性 例如,如果我

我对cosmosdb的dotnet v3 sdk中使用会话令牌做了一些研究,到目前为止,我发现了以下两个链接,它们为我提供了一些如何使用会话令牌的提示:和

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

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

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


提前谢谢

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

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

如果您有一个场景,其中在不同的进程中有多个Cosmos DB客户端实例,并且您希望读取自己的写保证,那么您有两个选择

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

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


  • 谢谢你的回答!我仍然有几个问题:这是否意味着会话令牌只能用于读取/查询请求,并且必须由每个写入请求更新?如果设置了ifEtagMatch标志,那么替换请求又如何保证etag是新的呢?另外,如果我想维护这个分布式互斥体来存储会话令牌,我是要为每个db还是每个分区存储会话令牌?提前谢谢!谢谢马克,我还有一个问题。在doc中,如果一个有界的过时数据库使用一个主数据库跨越多个区域,它将退化为一致的前缀一致性。在我们的例子中,读写操作只会发生在与master相同的区域(仅DR的多区域),它在这个特定的master区域中仍然是强的还是一致的前缀?我还尝试在新创建的db上使用任意大的LSN作为会话令牌,但没有给我任何错误,我传入的令牌是否未被处理?会话令牌将在每次写入请求(包括替换和Upsert)时更新。当您在Replace或Upsert的ItemRequestOptions参数中设置IfMatchEtag=itemResponse.Etag时,会选中Etag,例如,对于单个区域读取,您将获得具有有界陈旧性的强一致性。请参见此处的一致性保证,