Azure Cosmos DB で一貫性レベルを管理する

適用対象: NoSQL

この記事では、Azure Cosmos DB で一貫性レベルを管理する方法について説明します。 読者は、既定の一貫性レベルを構成する方法、既定の一貫性をオーバーライドする方法、セッション トークンを手動を管理する方法、および確率論的有界整合性制約 (PBS) メトリックを確認する方法について学習します。

アカウント レベルの整合性を変更するときは、アプリケーションを再デプロイし、これらの変更を適用するために必要なコード変更を行ってください。

Note

Azure を操作するには、Azure Az PowerShell モジュールを使用することをお勧めします。 作業を開始するには、Azure PowerShell のインストールに関する記事を参照してください。 Az PowerShell モジュールに移行する方法については、「AzureRM から Az への Azure PowerShell の移行」を参照してください。

既定の整合性レベルを構成する

既定の整合性レベルは、クライアントによって既定で使用される整合性レベルです。

既定の一貫性レベルを表示または変更するには、Azure portal にサインインします。 Azure Cosmos DB アカウントを見つけて、[既定の整合性] ウィンドウを開きます。 目的の一貫性レベルを新しい既定として選択し、 [保存] を選択します。 Azure portal では、音符によるさまざまな一貫性レベルの視覚化も提供しています。

Azure portal の一貫性メニュー

既定の一貫性レベルを上書きする

クライアントは、サービスによって設定された既定の一貫性レベルを上書きできます。 整合性レベルは要求ごとに設定できます。この設定によって、アカウント レベルで設定される既定の整合性レベルがオーバーライドされます。

ヒント

整合性は、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)

セッション トークンを利用する

Azure Cosmos DB の整合性レベルの 1 つとして、"セッション" の整合性があります。 これは、Azure Cosmos DB アカウントに既定で適用されるレベルです。 セッションの整合性を使用すると、Azure Cosmos DB に対する新しい書き込み要求ごとに、新しい SessionToken が割り当てられます。 CosmosClient は、各読み取り/クエリ要求にこのトークンを内部的に使用して、設定された一貫性レベルが維持されるようにします。

一部のシナリオでは、ユーザーがこのセッションを管理する必要があります。 複数のノードを持ち、各ノードに CosmosClient の独自のインスタンスがあるような、Web アプリケーションについて考えます。 (Web 層間で一貫して独自の書き込みを読み取ることができるようにするために) これらのノードが同じセッションに参加するようにする場合は、cookie または他のメカニズムを使って、書き込みアクションの FeedResponse<T> からエンド ユーザーに SessionToken を送信し、そのトークンが Web 層に戻され、最終的に以降の読み取りのために CosmosClient に送られるようにする必要があります。 Azure Load Balancer のように、要求間でセッション アフィニティを保持しないラウンドロビン ロード バランサーを使っている場合、読み取りが、セッションが作成された書き込み要求に対するものとは異なるノードに到達する可能性があります。

前に説明したように Azure Cosmos DB SessionToken をフローさせないと、一定の期間、一貫性のない読み取り結果が発生する可能性があります。

Azure Cosmos DB のセッション トークンはパーティションにバインドされており、1 つのパーティションに排他的に関連付けられています。 書き込みを確実に読み取るには、関連する項目に対して最後に生成されたセッショントークンを使用します。 セッション トークンを手動で管理するには、応答からセッション トークンを取得し、それらを要求ごとに設定します。 セッション トークンを手動で管理する必要がない場合は、これらのサンプルを使用する必要はありません。 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)

確率的有界整合性制約 (PBS) メトリックを監視する

最終的な整合性は、どのくらい最終的でしょうか。 平均的なケースでは、バージョン履歴と時刻に関して、古さの限度を提示できます。 確率的有界整合性制約 (PBS) メトリックは、古さの可能性を定量化し、それをメトリックとして表示します。

PBS メトリックを表示するには、Azure portal で Azure Cosmos DB アカウントに移動します。 [メトリック(クラシック)] ペインを開き、[整合性] タブを選びます。[ワークロードに基づく、厳密に一貫性のある読み取りの確率 (PBS を参照)] という名前のグラフを確認します。

Azure portal の PBS グラフ

次のステップ

データの競合を管理する方法について学習するか、Azure Cosmos DB に関する次の主要概念に進んでください。 次の記事をご覧ください。