パーティション間でスループットを再分散する (プレビュー)

適用対象: NoSQL MongoDB

Azure Cosmos DB の既定では、データベースまたはコンテナーのプロビジョニング済みスループットをすべての物理パーティションに均等に分散するようになっています。 ただし、ワークロードの偏りやパーティション キーの選択により、特定の論理 (したがって物理) パーティションで他のパーティションよりも多くのスループットを必要とするシナリオが発生する可能性があります。 このようなシナリオでは、Azure Cosmos DB を使用すると、プロビジョニングされたスループットを物理パーティション間で再分散できます。 パーティション間でスループットを再分散すると、最もホットなパーティションに基づいて全体的なスループットを構成しなくても、パフォーマンス向上を実現しやすくなります。

スループット再分散機能は、プロビジョニングされたスループット (手動および自動スケーリング) を使用するデータベースとコンテナーに適用され、サーバーレス コンテナーには適用されません。 Azure Cosmos DB PowerShell または Azure CLI コマンドを使用して、物理パーティションごとのスループットを変更できます。

この機能を使用する状況

一般に、次の両方が当てはまるシナリオでは、この機能を使用することをお勧めします。

  • 全体的な 429 応答の率が常に 1 - 5% を超えている
  • 一貫性のある予測可能なホット パーティションがある

429 応答が表示されず、エンド ツー エンドの待機時間が許容できるものである場合は、パーティションごとに RU/秒を再構成する処置は必要ありません。 "すべてのパーティション" でワークロードのトラフィックが一貫していて、予測不能なスパイクがときおり発生する場合には、自動スケーリングバースト容量 (プレビュー) を使用することをお勧めします。 自動スケーリングとバースト容量により、スループット要件が満たされることが確実になります。 パーティションあたりの RU/s の量が少ない場合は、パーティション マージ (プレビュー) を使用して、パーティションの数を減らし、同じプロビジョニングされたスループットの合計に対してパーティションあたりの RU/秒を増やすこともできます。

シナリオ例

小売店で発生するトランザクションを追跡するワークロードがあるとします。 ほとんどのクエリは StoreId によるものであるため、StoreId によってパーティション分割します。 ただし、一定期間にわたって一部の店舗は他の店舗よりもアクティビティが多く、ワークロードを処理するために、より多くのスループットを必要とすることがわかりました。 これらの StoreId に対する要求のレート制限 (429) が発生しており、全体的な 429 応答の率は 1 - 5% を超えています。 一方、他の店舗はそれほどアクティブではなく、必要なスループットも少なくなります。 パフォーマンス向上のためにスループットをどのように再分散できるかを見てみましょう。

手順 1: より多くのスループットが必要な物理パーティションを特定する

ホット パーティションがあるかどうかを確認するには、2 つの方法があります。

オプション 1: Azure Monitor のメトリックを使用する

ホット パーティションがあるかどうかを確認するには、[分析情報]>[スループット]>[Normalized RU Consumption (%) By PartitionKeyRangeID](PartitionKeyRangeID ごとの正規化された RU 消費量 (%)) に移動します。 フィルター処理して、特定のデータベースとコンテナーを表示します。

各 PartitionKeyRangeId は、1 つの物理パーティションにマップされます。 正規化された RU 消費量が他のパーティションよりも常に多い PartitionKeyRangeId を探します。 たとえば、1 つの値は一貫して 100% ですが、他の値は 30% 以下である場合です。 このようなパターンは、ホット パーティションを示している可能性があります。

ホット パーティションが含まれる [PartitionKeyRangeID ごとの正規化された RU 消費量] グラフのスクリーンショット。

オプション 2: 診断ログを使用する

診断ログの CDBPartitionKeyRUConsumption の情報を使用して、第 2 レベルの粒度で最も RU/秒を消費している論理パーティション キー (および対応する物理パーティション) に関する詳細情報を取得できます。 サンプル クエリでは、説明のみを目的として 24 時間を使用しています。パターンを理解するには、少なくとも 7 日間の履歴を使用することをお勧めします。

一定期間にわたって最も RU/秒を消費している物理パーティション (PartitionKeyRangeId) を見つけます

CDBPartitionKeyRUConsumption 
| where TimeGenerated >= ago(24hr)
| where DatabaseName == "MyDB" and CollectionName == "MyCollection" // Replace with database and collection name
| where isnotempty(PartitionKey) and isnotempty(PartitionKeyRangeId)
| summarize sum(RequestCharge) by bin(TimeGenerated, 1s), PartitionKeyRangeId
| render timechart

特定の物理パーティションについて、毎時間最も RU/秒を消費している上位 10 個の論理パーティション キーを見つけます

CDBPartitionKeyRUConsumption 
| where TimeGenerated >= ago(24hour)
| where DatabaseName == "MyDB" and CollectionName == "MyCollection" // Replace with database and collection name
| where isnotempty(PartitionKey) and isnotempty(PartitionKeyRangeId)
| where PartitionKeyRangeId == 0 // Replace with PartitionKeyRangeId 
| summarize sum(RequestCharge) by bin(TimeGenerated, 1hour), PartitionKey
| order by sum_RequestCharge desc | take 10

手順 2: 各物理パーティションのターゲット RU/秒を決定する

物理パーティションごとに現在の RU/秒を確認する

まず、各物理パーティションの現在の RU/秒を確認します。 Azure Monitor メトリックである PhysicalPartitionThroughput を使用し、PhysicalPartitionId ディメンションで分割して、物理パーティションごとの 1 秒あたりの RU 数を確認できます。

または、これまでにパーティションごとのスループットを変更していない場合は、この式を使用できます: Current RU/s per partition = Total RU/s / Number of physical partitions

プロビジョニングされたスループット (RU/秒) のスケーリングに関するベスト プラクティス」の記事にあるガイダンスに従って、物理パーティションの数を決定します。

PowerShell の Get-AzCosmosDBSqlContainerPerPartitionThroughput および Get-AzCosmosDBMongoDBCollectionPerPartitionThroughput コマンドを使用して、各物理パーティションの現在の RU/秒を読み取ることもできます。

Install-Module を使って、プレリリース機能が有効になっている Az.CosmosDB モジュールをインストールします。

$parameters = @{
    Name = "Az.CosmosDB"
    AllowPrerelease = $true
    Force = $true
}
Install-Module @parameters

Get-AzCosmosDBSqlContainerPerPartitionThroughput または Get-AzCosmosDBSqlDatabasePerPartitionThroughput コマンドを使用して、各物理パーティションの現在の RU/秒を読み取ります。


// Container with dedicated RU/s
$somePartitionsDedicatedRUContainer = Get-AzCosmosDBSqlContainerPerPartitionThroughput `
                    -ResourceGroupName "<resource-group-name>" `
                    -AccountName "<cosmos-account-name>" `
                    -DatabaseName "<cosmos-database-name>" `
                    -Name "<cosmos-container-name>" `
                    -PhysicalPartitionIds ("<PartitionId>", "<PartitionId">)

$allPartitionsDedicatedRUContainer = Get-AzCosmosDBSqlContainerPerPartitionThroughput `
                    -ResourceGroupName "<resource-group-name>" `
                    -AccountName "<cosmos-account-name>" `
                    -DatabaseName "<cosmos-database-name>" `
                    -Name "<cosmos-container-name>" `
                    -AllPartitions

// Database with shared RU/s
$somePartitionsSharedThroughputDatabase = Get-AzCosmosDBSqlDatabasePerPartitionThroughput `
                    -ResourceGroupName "<resource-group-name>" `
                    -AccountName "<cosmos-account-name>" `
                    -DatabaseName "<cosmos-database-name>" `
                    -PhysicalPartitionIds ("<PartitionId>", "<PartitionId">)

$allPartitionsSharedThroughputDatabase = Get-AzCosmosDBSqlDatabasePerPartitionThroughput `
                    -ResourceGroupName "<resource-group-name>" `
                    -AccountName "<cosmos-account-name>" `
                    -DatabaseName "<cosmos-database-name>" `
                    -AllPartitions

ターゲット パーティションの RU/秒を決定する

次に、最もホットな物理パーティションに指定する 1 秒あたりの RU 数を決定しましょう。 このセットをターゲット パーティションと呼びましょう。 任意の物理パーティションに含めることができる最大 RU/秒は 10,000 RU/秒です。

どちらの方法が最適かは各自のビジネス要件によって変わります。 一般的なアプローチを次に示します。

  • RU/秒をパーセンテージで増やし、429 応答の率を測定し、目的のスループットが達成されるまで繰り返します。
    • 適切なパーセンテージがわからない場合、控えめに最初は 10% とすることができます。
    • ワークロードのスループットの大部分がこの物理パーティションで必要とされていることが既にわかっている場合は、最初に RU/秒を 2 倍にするか、最大値の 10,000 RU/秒 (いずれか小さい方) に引き上げます。
  • RU/秒を Total consumed RU/s of the physical partition + (Number of 429 responses per second * Average RU charge per request to the partition) に引き上げる
    • このアプローチは、要求にレート制限がない場合の "実際の" RU/秒の消費量を見積もろうとするものです。

ソース パーティションの RU/秒を決定する

最後に、他の物理パーティションに対して維持する 1 秒あたりの RU 数を決定しましょう。 この選択により、ターゲット物理パーティションがスループットを取得する元のパーティションが決定されます。

PowerShell API には、RU/秒を再分散するソース パーティションを少なくとも 1 つ指定する必要があります。 再分散後に各物理パーティションに必要なカスタムの最小スループットを指定することもできます。 指定しない場合、既定では、Azure Cosmos DB によって、各物理パーティションの再分散後に少なくとも 100 RU/秒が確保されます。 最小スループットを明示的に指定することをお勧めします。

どちらの方法が最適かは各自のビジネス要件によって変わります。 一般的なアプローチを次に示します。

  • すべてのソース パーティションから RU/秒を均等に取得する (<= 10 のパーティションがある場合に最適)
    • 各ソース物理パーティションに対するオフセットに必要な量を計算します。 Offset = Total desired RU/s of target partition(s) - total current RU/s of target partition(s)) / (Total physical partitions - number of target partitions)
    • 各ソース パーティションの最小スループットを割り当てる = Current RU/s of source partition - offset
  • 最もアクティブなパーティションから RU/秒を取得する
    • Azure Monitor メトリックと診断ログを使用して、トラフィックまたは要求のボリュームが最も少ない物理パーティションを特定する
    • 各ソース物理パーティションに対するオフセットに必要な量を計算します。 Offset = Total desired RU/s of target partition(s) - total current RU/s of target partition) / Number of source physical partitions
    • 各ソース パーティションの最小スループットを割り当てる = Current RU/s of source partition - offset

手順 3: パーティション間のスループットをプログラムで変更する

PowerShell コマンド Update-AzCosmosDBSqlContainerPerPartitionThroughput を使用してスループットを再分散できます。

次の例を理解するために、合計 6000 RU/秒 (手動での 6000 RU/秒または自動スケーリングによる 6000 RU/秒) と 3 つの物理パーティションを持つコンテナーがある例を見てみましょう。 分析に基づいて、次のレイアウトが必要です。

  • 物理パーティション 0: 1000 RU/秒
  • 物理パーティション 1: 4000 RU/秒
  • 物理パーティション 2: 1000 RU/秒

ソース パーティションとしてパーティション 0 と 2 を指定し、再分散後に 1000 RU/秒の最小 RU/秒を持つ必要があることを指定します。 パーティション 1 がターゲット パーティションであり、4000 RU/秒を指定する必要があります。

専用 RU/秒のコンテナーの Update-AzCosmosDBSqlContainerPerPartitionThroughput、または共有 RU/秒を使用するデータベースの Update-AzCosmosDBSqlDatabasePerPartitionThroughput コマンドを使用して、物理パーティション間でスループットを再配布します。 共有スループット データベースでは、物理パーティションの ID は GUID 文字列で表されます。

$SourcePhysicalPartitionObjects =  @()
$SourcePhysicalPartitionObjects += New-AzCosmosDBPhysicalPartitionThroughputObject -Id "0" -Throughput 1000
$SourcePhysicalPartitionObjects += New-AzCosmosDBPhysicalPartitionThroughputObject -Id "2" -Throughput 1000

$TargetPhysicalPartitionObjects =  @()
$TargetPhysicalPartitionObjects += New-AzCosmosDBPhysicalPartitionThroughputObject -Id "1" -Throughput 4000

// Container with dedicated RU/s
Update-AzCosmosDBSqlContainerPerPartitionThroughput `
    -ResourceGroupName "<resource-group-name>" `
    -AccountName "<cosmos-account-name>" `
    -DatabaseName "<cosmos-database-name>" `
    -Name "<cosmos-container-name>" `
    -SourcePhysicalPartitionThroughputObject $SourcePhysicalPartitionObjects `
    -TargetPhysicalPartitionThroughputObject $TargetPhysicalPartitionObjects

// Database with shared RU/s
Update-AzCosmosDBSqlDatabasePerPartitionThroughput `
    -ResourceGroupName "<resource-group-name>" `
    -AccountName "<cosmos-account-name>" `
    -DatabaseName "<cosmos-database-name>" `
    -SourcePhysicalPartitionThroughputObject $SourcePhysicalPartitionObjects `
    -TargetPhysicalPartitionThroughputObject $TargetPhysicalPartitionObjects

再分散が完了したら、Azure Monitor で PhysicalPartitionThroughput メトリックを表示して変更を確認できます。 物理パーティションごとの 1 秒あたりの RU 数を確認するには、PhysicalPartitionId ディメンションで分割します。

必要に応じて、物理パーティションごとの RU/秒をリセットして、コンテナーの RU/秒がすべての物理パーティションに均等に分散されるようにすることもできます。

専用 RU/秒のコンテナーには Update-AzCosmosDBSqlContainerPerPartitionThroughput コマンドを使用し、パラメーター -EqualDistributionPolicy を持つ共有 RU/秒を持つデータベースの場合は Update-AzCosmosDBSqlDatabasePerPartitionThroughput コマンドを使用して、RU/秒をすべての物理パーティションに均等に分散します。


// Container with dedicated RU/s
$resetPartitionsDedicatedRUContainer = Update-AzCosmosDBSqlContainerPerPartitionThroughput `
                    -ResourceGroupName "<resource-group-name>" `
                    -AccountName "<cosmos-account-name>" `
                    -DatabaseName "<cosmos-database-name>" `
                    -Name "<cosmos-container-name>" `
                    -EqualDistributionPolicy

// Database with dedicated RU/s
$resetPartitionsSharedThroughputDatabase = Update-AzCosmosDBSqlDatabasePerPartitionThroughput `
                    -ResourceGroupName "<resource-group-name>" `
                    -AccountName "<cosmos-account-name>" `
                    -DatabaseName "<cosmos-database-name>" `
                    -EqualDistributionPolicy

手順 4: RU/秒の消費量を確認して監視する

再分散が完了したら、Azure Monitor で PhysicalPartitionThroughput メトリックを表示して変更を確認できます。 物理パーティションごとの 1 秒あたりの RU 数を確認するには、PhysicalPartitionId ディメンションで分割します。

全体的な 429 応答の率と RU/秒の消費量を監視することをお勧めします。 詳細については、手順 1 を見直して、期待するパフォーマンスが達成されたことを確認します。

変更後、全体的なワークロードが変わっていないと仮定すると、ターゲットとソースの両方の物理パーティションの正規化された RU 消費量は以前よりも多くなる可能性があります。 正規化された RU 消費量が多くなることは、予想された動作です。 基本的には、各パーティションで実際に消費する必要がある値に近い RU/秒を割り当てたので、正規化された RU 消費量が多くなることは、各パーティションで割り当てられた RU/秒が完全に利用されていることを意味します。 また、ホット パーティションで要求を処理するための RU/秒が増えたので、全体的な 429 例外の発生率は減少することがわかります。

制限事項

プレビュー資格条件

プレビューを使用するには、Azure Cosmos DB アカウントが次のすべての条件を満たしている必要があります:

  • Azure Cosmos DB アカウントでは、NoSQL 用 API または MongoDB 用 API を使用しています。
    • MongoDB 用 API を使用している場合、バージョンは 3.6 以上である必要があります。
  • Azure Cosmos DB アカウントは、プロビジョニングされたスループット (手動または自動スケーリング) を使用します。 パーティション間でのスループットの分散は、サーバーレス アカウントには適用されません。

プレビューを使用するためにサインアップする必要はありません。 この機能を使用するには、PowerShell または Azure CLI コマンドを使用して、リソースの物理パーティション間でスループットを再配布します。

次のステップ

プロビジョニングされたスループットを使用する方法については、次の記事を参照してください。