在 Azure Cosmos DB 中管理一致性级别

适用范围: NoSQL

本文介绍了如何在 Azure Cosmos DB 中管理一致性级别。 你将了解如何配置默认一致性级别、替代默认一致性、手动管理会话令牌以及了解概率有限过期 (PBS) 指标。

更改帐户级别的一致性时,请确保重新部署应用程序并进行任何必要的代码修改,以便应用这些更改。

注意

建议使用 Azure Az PowerShell 模块与 Azure 交互。 请参阅安装 Azure PowerShell 以开始使用。 若要了解如何迁移到 Az PowerShell 模块,请参阅 将 Azure PowerShell 从 AzureRM 迁移到 Az

配置默认一致性级别

若要详细了解默认一致性级别,请参阅 Azure Cosmos DB 中的一致性级别

若要查看或修改默认一致性级别,

  1. 登录到 Azure 门户

  2. 找到你的 Azure Cosmos DB 帐户,打开“默认一致性”窗格。

  3. 选择你希望用作新的默认值的一致性级别,然后选择“保存”

Azure 门户还使用音符提供了不同一致性级别的可视化效果。

Azure 门户中一致性菜单的屏幕截图。

替代默认一致性级别

该服务设置默认一致性级别,但客户端可以替代它。 可以在每个请求上设置一致性级别,这将替代在帐户级别设置的默认一致性级别。

提示

只能在 SDK 实例或请求级别放宽一致性要求。 若要从较弱的一致性移动到更强的一致性,请更新 Azure Cosmos DB 帐户的默认一致性。

提示

替代默认一致性级别的操作仅适用于 SDK 客户端中的读取。 默认情况下,为强一致性配置的帐户仍会同步写入数据并将其复制到帐户中的每个区域。 当 SDK 客户端实例或请求用会话或较弱的一致性替代此级别时,将使用单个副本执行读取。 有关详细信息,请参阅一致性级别和吞吐量

.NET SDK

// Override consistency at the client level
documentClient = new DocumentClient(new Uri(endpoint), authKey, connectionPolicy, ConsistencyLevel.Eventual);

// Override consistency at the request level via request options
RequestOptions requestOptions = new RequestOptions { ConsistencyLevel = ConsistencyLevel.Eventual };

var response = await client.ReadDocumentAsync(collectionUri, document, requestOptions);

Java V4 SDK

Java SDK V4 (Maven com.azure::azure-cosmos) 异步 API


CosmosAsyncClient client =
        new CosmosClientBuilder()
                .endpoint(HOST)
                .key(MASTER_KEY)
                .consistencyLevel(ConsistencyLevel.EVENTUAL)
                .buildAsyncClient();

Java V2 SDK

Async Java V2 SDK(Maven com.microsoft.azure::azure-cosmosdb)

// Override consistency at the client level
ConnectionPolicy policy = new ConnectionPolicy();

AsyncDocumentClient client =
        new AsyncDocumentClient.Builder()
                .withMasterKey(this.accountKey)
                .withServiceEndpoint(this.accountEndpoint)
                .withConsistencyLevel(ConsistencyLevel.Eventual)
                .withConnectionPolicy(policy).build();

Node.js/JavaScript/TypeScript SDK

// Override consistency at the client level
const client = new CosmosClient({
  /* other config... */
  consistencyLevel: ConsistencyLevel.Eventual
});

// Override consistency at the request level via request options
const { body } = await item.read({ consistencyLevel: ConsistencyLevel.Eventual });

Python SDK

# Override consistency at the client level
connection_policy = documents.ConnectionPolicy()
client = cosmos_client.CosmosClient(self.account_endpoint, {
                                    'masterKey': self.account_key}, connection_policy, documents.ConsistencyLevel.Eventual)

Go 软件开发工具包 (SDK)

在请求中定义一致性级别:

container, _ := c.NewContainer("moviesdb", "movies")

container.NewQueryItemsPager("select * from c", azcosmos.NewPartitionKey(), &azcosmos.QueryOptions{
		ConsistencyLevel: azcosmos.ConsistencyLevelEventual.ToPtr(),
})

container.ReadItem(context.Background(), azcosmos.NewPartitionKeyString("Quentin Tarantino"), "Pulp Fiction", &azcosmos.ItemOptions{
		ConsistencyLevel: azcosmos.ConsistencyLevelStrong.ToPtr(),
})

利用会话令牌

Azure Cosmos DB 中的一个一致性级别是 会话 一致性。 此级别是应用于 Azure Cosmos DB 帐户的默认级别。 在处理会话一致性时,每次新的写入请求都会向 Azure Cosmos DB 分配一个新的 SessionToken。 CosmosClient 使用此令牌在每次读取/查询请求中进行内部操作,以确保保持设定的一致性级别。

在某些情况下,需要自行管理此会话。 考虑具有多个节点的 Web 应用程序,每个节点都有自己的 CosmosClient 实例。 如果希望这些节点参与同一会话(能够跨 Web 层一致地读取自己的写入),则必须使用 Cookie 或其他某种机制将写操作的 SessionToken 从 FeedResponse<T> 发送给最终用户,并确保该令牌回流到 Web 层,最终由 CosmosClient 用于后续的读取操作。 如果使用轮循机制负载均衡器,该负载均衡器不维护请求(例如 Azure 负载均衡器)之间的会话亲和性,则读取可能会登陆创建会话的写入请求的不同节点上。

如果不跨 Azure Cosmos DB SessionToken 流动,则最终可能会有一段时间的读取结果不一致。

Azure Cosmos DB 中的会话令牌是分区绑定的,这意味着它们只与一个分区相关联。 为了确保可以读取写入,请使用上次为相关项生成的会话令牌。 若要手动管理会话令牌,请从响应中获取会话令牌并针对每个请求设置它们。 如果不需手动管理会话令牌,则不需要使用这些示例。 SDK 会自动跟踪会话令牌。 如果未手动设置会话令牌,则默认情况下,SDK 使用最新的会话令牌。

.NET SDK

var response = await client.ReadDocumentAsync(
                UriFactory.CreateDocumentUri(databaseName, collectionName, "SalesOrder1"));
string sessionToken = response.SessionToken;

RequestOptions options = new RequestOptions();
options.SessionToken = sessionToken;
var response = await client.ReadDocumentAsync(
                UriFactory.CreateDocumentUri(databaseName, collectionName, "SalesOrder1"), options);

Java V4 SDK

Java SDK V4 (Maven com.azure::azure-cosmos) 异步 API


// Get session token from response
CosmosItemResponse<JsonNode> response = container.readItem(itemId, new PartitionKey(partitionKey), JsonNode.class).block();
String sessionToken = response.getSessionToken();

// Resume the session by setting the session token on the RequestOptions
CosmosItemRequestOptions options = new CosmosItemRequestOptions();
options.setSessionToken(sessionToken);
CosmosItemResponse<JsonNode> response2 = container.readItem(itemId, new PartitionKey(partitionKey), JsonNode.class).block();

Java V2 SDK

Async Java V2 SDK(Maven com.microsoft.azure::azure-cosmosdb)

// Get session token from response
RequestOptions options = new RequestOptions();
options.setPartitionKey(new PartitionKey(document.get("mypk")));
Observable<ResourceResponse<Document>> readObservable = client.readDocument(document.getSelfLink(), options);
readObservable.single()           // we know there will be one response
  .subscribe(
      documentResourceResponse -> {
          System.out.println(documentResourceResponse.getSessionToken());
      },
      error -> {
          System.err.println("an error happened: " + error.getMessage());
      });

// Resume the session by setting the session token on RequestOptions
RequestOptions options = new RequestOptions();
requestOptions.setSessionToken(sessionToken);
Observable<ResourceResponse<Document>> readObservable = client.readDocument(document.getSelfLink(), options);

Node.js/JavaScript/TypeScript SDK

// Get session token from response
const { headers, item } = await container.items.create({ id: "meaningful-id" });
const sessionToken = headers["x-ms-session-token"];

// Immediately or later, you can use that sessionToken from the header to resume that session.
const { body } = await item.read({ sessionToken });

Python SDK

// Get the session token from the last response headers
item = client.ReadItem(item_link)
session_token = client.last_response_headers["x-ms-session-token"]

// Resume the session by setting the session token on the options for the request
options = {
    "sessionToken": session_token
}
item = client.ReadItem(doc_link, options)

Go 软件开发工具包 (SDK)

// Get the session token from the create item response
resp, _ := container.CreateItem(context.Background(), azcosmos.NewPartitionKeyString("Quentin Tarantino"), movie, &azcosmos.ItemOptions{
	ConsistencyLevel: azcosmos.ConsistencyLevelSession.ToPtr(),
})

// Use the session token to read the item
container.ReadItem(context.Background(), azcosmos.NewPartitionKeyString("Quentin Tarantino"), movieId, &azcosmos.ItemOptions{
	SessionToken: resp.SessionToken,
})

监视概率有限过期性指标

最终一致性的最终程度如何? 对于普通情况,我们可以提供版本历史和时间方面的有界一致性。 概率有限过期(PBS)指标尝试量化过期的可能性,并将其显示为指标。

若要查看 PBS 指标,

  1. 转到 Microsoft Azure 门户中的 Azure Cosmos DB 帐户。

  2. 打开 “指标”(经典) 窗格,然后选择“ 一致性 ”选项卡。

  3. 查看名为“基于工作负载的强一致性读取的概率(请参阅 PBS)”的图。

Azure 门户中概率有界陈旧性图的屏幕截图。

后续步骤

详细了解如何管理数据冲突,或者继续了解 Azure Cosmos DB 中的下一个关键概念。