Azure Cosmos DB for MongoDB での書き込みパフォーマンスを最適化する

適用対象: MongoDB

書き込みパフォーマンスを最適化すると、Azure Cosmos DB for MongoDB の無制限のスケールを最大限に活用できます。 他のマネージド MongoDB サービスとは異なり、MongoDB 用 API ではコレクションが自動的かつ透過的にシャード化されて (シャード化されたコレクションを使用したとき)、無限にスケーリングされます。

データベースとコレクションから最大限の書き込み性能を引き出すには、データの書き込み方法でもこのことを念頭に置き、シャード間にデータを並列化して分散する必要があります。 この記事では、書き込みパフォーマンスを最適化するためのベスト プラクティスについて説明します。

シャード間に負荷を分散する

MongoDB 用 API のシャード化されたコレクションにデータを書き込むと、データは小さなスライスに分割 (シャード化) され、シャード キー フィールドの値に基づいて各シャードに書き込まれます。 各スライスは、1 つの一意のシャード キー値を含むドキュメントのみを格納する、仮想マシンの小さな部分と考えることができます。

アプリケーションで 1 つのシャードに大量のデータを書き込んだ場合、すべてのシャードに負荷が分散されず、代わりにアプリのスループットが 1 つのシャードに集中するので、効率的ではなくなります。 一意のシャード キー値を持つ多くのドキュメントに並列で書き込むと、書き込み負荷がコレクション全体に均等に分散されます。

これを行う例の 1 つは、カテゴリ フィールドにシャード化された製品カタログ アプリケーションです。 一度に 1 つのカテゴリ (シャード) に書き込むのではなく、すべてのカテゴリに同時に書き込む方がよい方法であり、最大の書き込みスループットが実現されます。

インデックスの数を減らす

インデックスの作成は、データのクエリにかかる時間が大幅に短縮される優れた機能です。 最も柔軟なクエリ エクスペリエンスを実現するため、MongoDB 用 API ではデータでワイルドカード インデックスが既定で有効になり、すべてのフィールドに対してクエリを高速に実行できます。 ただし、ワイルドカード インデックスを含むすべてのインデックスで、書き込みによってコレクションとインデックスが変更されるので、データの書き込み時に追加の負荷が発生します。

クエリをサポートするために必要なインデックスだけにして、インデックスの数を減らすと、書き込み速度が向上し、コストが削減されます。 一般的な規則として、次のことをお勧めします。

  • フィルター処理するすべてのフィールドには、対応する単一フィールド インデックスが必要です。 このオプションを使用すると、複数フィールドのフィルター処理も有効になります。
  • 並べ替えに使用するフィールドのグループには、そのグループに対する複合インデックスが必要です。

MongoDB ドライバーで ordered を false に設定する

MongoDB ドライバーの既定では、データの書き込み時には ordered オプションが "true" に設定され、各ドキュメントは 1 つずつ順番に書き込まれます。 このオプションを使用すると、各書き込み要求で前の要求の完了を待つ必要があるため、書き込みのパフォーマンスが低下します。 データを書き込むときにこのオプションを false に設定すると、パフォーマンスが向上します。

db.collection.insertMany(
   [ <doc1> , <doc2>, ... ],
   {
      ordered: false
   }
)

最適なバッチ サイズとスレッド数になるように調整する

書き込みをスケーリングするには、多くのスレッドやプロセスの間での書き込み操作の並列化が重要です。 MongoDB 用 API では、プロセスやスレッドごとに最大 1,000 ドキュメントの一括書き込みが受け付けられます。

プロセスやスレッドごとに一度に 1,000 を超えるドキュメントを書き込む場合、insertMany() などのクライアント関数を約 1,000 ドキュメントに制限する必要があります。 そうしないと、クライアントは次のバッチに進む前に各バッチのコミットを待機する必要があります。 場合によっては、1,000 ドキュメントより少なく、またはわずかに多くなるようにバッチを分割すると、高速になります。

次のステップ