AI エージェント向け: ドキュメントインデックスは https://www.mongodb.com/ja-jp/docs/llms.txt で利用できます。すべてのページの markdown バージョンは、いずれかの URL パスに .md を追加することで利用できます。
Docs Menu

コレクションの再シャーディング

理想的なシャードキーを使用すると、 MongoDB は一般的なクエリ パターンにしながら、ドキュメントをクラスター全体に均等に分散できます。シャードキーが最適でないと、データ分散が不均等になるため、パフォーマンスやスケーリングの問題が発生する可能性があります。コレクションのシャードキーを変更して、クラスター全体のデータの分散を変更できます。

MongoDB 8.0 以降では、同じシャードキーでコレクションを 再シャーディング することができ、シャードキーを変更せずに新しいシャードを含めたり、別のゾーンにデータを再配布したりできます。同じシャードキーにリシャーディングするには、forceRedistribution を true に設定します。

MongoDB 8.0.10 以降、時系列コレクションを再シャーディング できます。時系列コレクション内のすべてのシャードは、リシャードするにはバージョン 8.0.10 以降を実行する必要があります。

注意

コレクションを再シャーディングする前に、一般的なパフォーマンスとスケーリングの問題に関する情報と、その修正方法に関するアドバイスについては、 「 シャードキーのトラブルシューティング 」をお読みください。

  • 一度にリシャーディングできるコレクションは 1 つだけです。

  • writeConcernMajorityJournalDefaultはtrueである必要があります。

  • 一意の制約があるコレクションを再シャーディングするには、新しいシャードキーが既存の一意なインデックスの一意なインデックス要件を満たす必要があります。

  • 次のコマンドと対応する shell メソッドは、再シャーディング操作の進行中に再シャーディングされるコレクションではサポートされていません。

  • 次のいずれかの操作を実行する場合、その操作は再シャーディングが完了するまで待機してから実行されます。

  • リシャーディングしているコレクションが Atlas Search を使用している場合、リシャーディング操作の完了時に検索インデックスは使用できなくなります。再シャーディング操作が完了してから、検索インデックスを手動で再構築する必要があります。

コレクションを再シャーディングする前に、次の要件を満たしていることを確認してください。

  • アプリケーションは、影響を受けるコレクションが書込みをブロックする期間を2 秒許容できます。 書込み (write) がブロックされている期間中、アプリケーションのレイテンシが増加します。

    ワークロードがこの要件を許容できない場合は、代わりにシャードキーの改良を検討してください。

  • データベースが次のリソース要件を満たしている。

    • 各受信者シャードで使用可能なストレージ領域が、少なくとも再シャーディングするコレクションのストレージサイズとその合計インデックスサイズの 2 倍をシャード数で割ったものであることを確認します。

      ( ( collection_storage_size + index_size ) * 2 ) / shard_count = storage_req

      例、ストレージサイズが 2 TB データと 400 GB インデックスのコレクションを考えてみましょう。これを 4 つのシャードに分散するには、次のものが必要です。

      ( ( 2 TB collection + 0.4 TB index ) * 2 ) / 4 shards = 1.2 TB storage

      このコレクション を再シャーディングするには、各シャードに 1.2 が必要です利用可能なストレージの TB

      MongoDB Atlasでは、再シャーディング操作のためにストレージの次の階層にアップグレードする必要がある場合があります。操作が完了したらダウングレードできます。

    • I/Oキャパシティーが50 % 未満であることを確認します。

    • CPU 負荷が80 % 未満であることを確認します。

    重要

    これらの要件はデータベースによって強制されません。 十分なリソースを割り当てられない場合、次の結果が発生する可能性があります。

    • データベースの容量が不足し、シャットダウンした

    • パフォーマンスの低下

    • 操作に予想よりも時間がかかる

    アプリケーションにトラフィックが少ない期間がある場合は、可能であれば、その時間中にコレクションに対してこの操作を実行します。

  • リシャーディングの前に、新しいシャードキーにインデックスを作成する必要はありません。リシャーディング操作、インデックスフェーズ中に必要なインデックスが自動的に構築されます。

  • インデックスのビルドは進行中ではありません。インデックスビルドが実行中どうかを確認するには、$currentOp を使用します。

    db.getSiblingDB("admin").aggregate( [
    { $currentOp : { idleConnections: true } },
    { $match: {
    $or: [
    { "op": "command", "command.createIndexes": { $exists: true } },
    { "op": "none", "msg": /^Index Build/ }
    ]
    }
    }
    ] )

    結果ドキュメントでは、 inprogフィールド値が空の配列の場合、インデックスビルドは進行中ではありません。

    {
    inprog: [],
    ok: 1,
    '$clusterTime': { ... },
    operationTime: <timestamp>
    }

注意

リシャーディングは書き込み集中型のプロセスであり、oplog のレートが増加する可能性があります。 次のことをしたい場合があります。

  • 固定の oplog サイズを設定して、oplog の無制限の増加を防ぎます。

  • oplog サイズを増やして 1 つ以上のセカンダリ ノードが古くなる可能性を最小限に抑えます。

詳細については、レプリカセットoplogのドキュメントを参照してください。

クエリフィルターに完全なシャードキーを含まないクエリには、 2 フェーズの書込みプロトコルが必要になる場合があります 。このプロトコルはクエリを複数のシャードにブロードキャストするため、パフォーマンスを大幅に低下させる可能性があります。

  • 新しいシャードキーではなく古いシャードキーを提供するクエリは、 2 フェーズ書込みプロトコルを使用します 。

  • deleteOne()メソッドは、クエリフィルターが完全なシャードキーまたは フィールドを使用していない場合、2_id フェーズ書込みプロトコルを使用します。

  • replaceOne()メソッドとupdateOne() メソッドでは以下の操作が実行されます。

    • クエリが完全なシャードキーを提供する場合、2 フェーズプロトコルは使用されません。

      • クエリが完全なシャードキーを提供せずに、_idフィールドを提供する場合、2 フェーズ書込みプロトコルを使用するかどうかは、upsert の値によって異なります。 upsert が true に設定されている場合、2 フェーズ書込みプロトコルが使用されます。 upsertが false の場合、2 フェーズ書込みプロトコルは使用されません。

      • クエリで完全なシャードキーも _idフィールドも提供されない場合、常に 2 フェーズ書込みプロトコルが使用されます。

  • 次のメソッドは、クエリフィルターが完全なシャードキーを使用していない場合に、 2 フェーズ書込みプロトコルを使用します。

最適なパフォーマンスを得るには、再シャーディング操作が完了した後にアプリケーションを更新して、これらの操作のクエリフィルターで新しいシャードキーを使用するようにします。

重要

コレクションを再シャーディングする前に、このタスクについてを確認し、手順セクションを最後までお読みください。

コレクションの再シャーディング操作では、シャードは次のようになります。

シャードは同時にドナーでも受信者でもあることができます。

コンフィギュレーションサーバーのプライマリは常にリシャーディング コーディネーターであり、リシャーディング操作の各フェーズを開始します。

1

コレクションの再シャーディング プロセスを開始する前に、バランサーをオフにする必要があります。 バランサー を無効にするには、こちらの を参照してください。

2

mongosに接続している間に、再シャーディングするコレクションと新しいシャードキーを指定するreshardCollectionコマンドを発行します。

db.adminCommand({
reshardCollection: "<database>.<collection>",
key: <shardkey>
})

MongoDB は、書込みをブロックする最大秒数を 2 秒に設定し、リシャーディング操作を開始します。

同じシャードキーにリシャーディングするには、forceRedistribution を true に設定します。

db.adminCommand({
reshardCollection: "<database>.<collection>",
key: <shardkey>,
forceRedistribution: true
})

sh.reshardCollection() を使用して、同じキーを持つコレクションを再シャーディングすることもできます。例については、「新しいシャードへのデータの再配布」を参照してください。

3

リシャーディング操作をモニターするには、 $currentOpパイプライン ステージを使用できます。

db.getSiblingDB("admin").aggregate([
{ $currentOp: { allUsers: true, localOps: false } },
{
$match: {
type: "op",
"originatingCommand.reshardCollection": "<database>.<collection>"
}
}
])

注意

更新された値を確認するには、前のパイプラインを継続的に実行する必要があります。

$currentOpパイプラインの出力は次のとおりです。

  • totalOperationTimeElapsedSecs: 経過したoptime (秒単位)

  • remainingOperationTimeEstimatedSecs: 現在のリシャーディング操作の推定残り時間(秒単位)。 新たにリシャーディング操作を開始すると、 -1として返されます。

    MongoDB 7.0 以降では、 リシャーディング操作中にコーディネーターで remainingOperationTimeEstimatedSecs も使用できます。

    remainingOperationTimeEstimatedSecs は悲観的な時間推定値に設定されています。

    • キャッチアップフェーズの推定時間は、比較的長い時間であるクローンフェーズ時間に設定されます。

    • 実際には、保留中の書込み操作が少ない場合、実際のキャッチアップ フェーズ時間は比較的短いです。

[
{
shard: '<shard>',
type: 'op',
desc: 'ReshardingRecipientService | ReshardingDonorService | ReshardingCoordinatorService <reshardingUUID>',
op: 'command',
ns: '<database>.<collection>',
originatingCommand: {
reshardCollection: '<database>.<collection>',
key: <shardkey>,
unique: <boolean>,
collation: { locale: 'simple' }
},
totalOperationTimeElapsedSecs: <number>,
remainingOperationTimeEstimatedSecs: <number>,
...
},
...
]
4

バランサーを有効にするには、こちら を参照してください。

リシャーディング操作の最小期間は常に 5 分です。

リシャーディング前または再シャーディング中に開始された再試行可能な書込みは、コレクションが最大 5 分間再シャーディングされた期間中に、および再シャーディングされた後に再試行できます。 5 分後、書き込みの決定的な結果が見つからず、その後書き込みを再試行しようとすると失敗し、 IncompleteTransactionHistoryエラーが発生します。

  • コレクションでAtlas Searchが使用されている場合、操作の完了後に検索インデックスは使用できなくなります。これを復元するには、検索インデックスを 手動で再ビルドします。

  • Queryable 暗号化を使用するコレクションはサポートされていません。

コレクション データの破損を避けるために、 _idの値がグローバルに一意でない場合、リシャーディング操作は失敗します。 _idの値が重複していると、チャンク移行が成功し ない 可能性もあります。 _id値が重複しているドキュメントがある場合は、それぞれから新しいドキュメントにデータをコピーしてから、重複するドキュメントを削除します。