Gerir níveis de consistência no Azure Cosmos DB

APLICA-SE A: NoSQL

Este artigo explica como gerenciar níveis de consistência no Azure Cosmos DB. Você aprende a configurar o nível de consistência padrão, substituir a consistência padrão, gerenciar manualmente os tokens de sessão e entender a métrica PBS (Probabilistically Bounded Staleness).

À medida que você altera a consistência do nível da conta, certifique-se de reimplantar seus aplicativos e fazer as modificações de código necessárias para aplicar essas alterações.

Nota

Recomendamos que utilize o módulo do Azure Az PowerShell para interagir com o Azure. Veja Instalar o Azure PowerShell para começar. Para saber como migrar para o módulo do Az PowerShell, veja Migrar o Azure PowerShell do AzureRM para o Az.

Configurar o nível de consistência predefinido

O nível de consistência padrão é o nível de consistência que os clientes usam por padrão.

Para exibir ou modificar o nível de consistência padrão, entre no portal do Azure. Encontre sua conta do Azure Cosmos DB e abra o painel Consistência padrão. Selecione o nível de consistência desejado como o novo padrão e, em seguida, selecione Salvar. O portal do Azure também fornece uma visualização de diferentes níveis de consistência com notas de música.

Menu Consistência no portal do Azure

Substituir o nível de consistência predefinido

Os clientes podem substituir o nível de consistência predefinido que está definido pelo serviço. O nível de consistência pode ser definido por solicitação, o que substitui o nível de consistência padrão definido no nível da conta.

Gorjeta

A consistência só pode ser relaxada no nível de instância ou solicitação do SDK. Para passar de uma consistência mais fraca para uma consistência mais forte, atualize a consistência padrão para a conta do Azure Cosmos DB.

Gorjeta

Substituir o nível de consistência padrão só se aplica a leituras dentro do cliente SDK. Uma conta configurada para consistência forte por padrão ainda gravará e replicará dados de forma síncrona para cada região da conta. Quando a instância ou solicitação do cliente SDK substitui isso por Session ou consistência mais fraca, as leituras serão executadas usando uma única réplica. Consulte Níveis de consistência e taxa de transferência para obter mais detalhes.

SDK do .NET

// 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 assíncrona


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

Java V2 SDKs

SDK Java V2 assíncrono (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();

SDK do Node.js/JavaScript/TypeScript

// 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)

Utilizar tokens de sessões

Um dos níveis de consistência no Azure Cosmos DB é a consistência da sessão . Este é o nível padrão aplicado às contas do Azure Cosmos DB por padrão. Ao trabalhar com consistência de sessão, cada nova solicitação de gravação no Azure Cosmos DB recebe um novo SessionToken. O CosmosClient usará esse token internamente com cada solicitação de leitura/consulta para garantir que o nível de consistência definido seja mantido.

Em alguns cenários, você mesmo precisa gerenciar essa sessão. Considere um aplicativo Web com vários nós, cada nó terá sua própria instância de CosmosClient. Se você quisesse que esses nós participassem da mesma sessão (para poder ler suas próprias gravações de forma consistente em todas as camadas da Web), você teria que enviar o SessionToken do FeedResponse<T> da ação de gravação para o usuário final usando um cookie ou algum outro mecanismo, e fazer com que esse token fluísse de volta para a camada da Web e, finalmente, para o CosmosClient para leituras subsequentes. Se você estiver usando um balanceador de carga round-robin que não mantenha afinidade de sessão entre solicitações, como o Balanceador de Carga do Azure, a leitura poderá potencialmente pousar em um nó diferente da solicitação de gravação, onde a sessão foi criada.

Se você não fluir o SessionToken do Azure Cosmos DB como descrito acima, poderá acabar com resultados de leitura inconsistentes por um tempo.

Os Tokens de Sessão no Azure Cosmos DB são associados a partições, o que significa que estão exclusivamente associados a uma partição. Para garantir que você possa ler suas gravações, use o token de sessão que foi gerado pela última vez para o(s) item(ns) relevante(s). Para gerenciar tokens de sessão manualmente, obtenha o token de sessão da resposta e defina-os por solicitação. Se você não precisar gerenciar tokens de sessão manualmente, não precisará usar esses exemplos. O SDK controla os tokens de sessão automaticamente. Se você não definir o token de sessão manualmente, por padrão, o SDK usará o token de sessão mais recente.

SDK do .NET

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 assíncrona


// 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 SDKs

SDK Java V2 assíncrono (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);

SDK do Node.js/JavaScript/TypeScript

// 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)

Monitorizar a métrica de Estagnação Limitada Probabilisticamente (PBS)

Quão eventual é a eventual consistência? Para o caso médio, podemos oferecer limites de obsoletos em relação ao histórico de versões e ao tempo. A métrica Probabilistically Bounded Staleness (PBS) tenta quantificar a probabilidade de estagnação e mostra-a como uma métrica.

Para exibir a métrica PBS, vá para sua conta do Azure Cosmos DB no portal do Azure. Abra o painel Métricas (Clássico) e selecione a guia Consistência. Observe o gráfico chamado Probabilidade de leituras altamente consistentes com base em sua carga de trabalho (consulte PBS).

Gráfico PBS no portal do Azure

Próximos passos

Saiba mais sobre como gerenciar conflitos de dados ou passe para o próximo conceito-chave no Azure Cosmos DB. Consulte os seguintes artigos: