理想的なシャードキーを使用すると、 MongoDB は一般的なクエリ パターンにしながら、ドキュメントをクラスター全体に均等に分散できます。シャードキーが最適でないと、データ分散が不均等になるため、パフォーマンスやスケーリングの問題が発生する可能性があります。コレクションのシャードキーを変更して、クラスター全体のデータの分散を変更できます。
MongoDB 8.0 以降では、同じシャードキーでコレクションを 再シャーディング することができ、シャードキーを変更せずに新しいシャードを含めたり、別のゾーンにデータを再配布したりできます。同じシャードキーにリシャーディングするには、forceRedistribution を true に設定します。
MongoDB 8.0.10 以降、時系列コレクションを再シャーディング できます。時系列コレクション内のすべてのシャードは、リシャードするにはバージョン 8.0.10 以降を実行する必要があります。
注意
コレクションを再シャーディングする前に、一般的なパフォーマンスとスケーリングの問題に関する情報と、その修正方法に関するアドバイスについては、 「 シャードキーのトラブルシューティング 」をお読みください。
このタスクについて
一度にリシャーディングできるコレクションは 1 つだけです。
writeConcernMajorityJournalDefaultはtrueである必要があります。一意の制約があるコレクションを再シャーディングするには、新しいシャードキーが既存の一意なインデックスの一意なインデックス要件を満たす必要があります。
次のコマンドと対応する shell メソッドは、再シャーディング操作の進行中に再シャーディングされるコレクションではサポートされていません。
リシャーディング操作の進行中、 クラスターでは以下のコマンドとメソッドはサポートされません。
警告
リシャーディング操作中に上記のコマンドのいずれかを使用すると、リシャーディング操作は失敗します。
リシャーディングしているコレクションが Atlas Search を使用している場合、再シャーディング操作の完了時に検索インデックスは使用できなくなります。再シャーディング操作が完了してから、検索インデックスを手動で再構築する必要があります。
始める前に
コレクションを再シャーディングする前に、次の要件を満たしていることを確認してください。
アプリケーションは、影響を受けるコレクションが書込みをブロックする期間を2 秒許容できます。 書込み (write) がブロックされている期間中、アプリケーションのレイテンシが増加します。
ワークロードがこの要件を許容できない場合は、代わりにシャードキーの改良を検討してください。
データベースが次のリソース要件を満たしている。
Ensure that the available storage space on each recipient shard is at least twice the storage size of the collection that you want to reshard plus its total index size, divided by the number of shards:
( ( collection_storage_size + index_size ) * 2 ) / shard_count = storage_req For example, consider a collection with a storage size of 2 TB data and a 400 GB index. To distribute it across four shards you'd need:
( ( 2 TB collection + 0.4 TB index ) * 2 ) / 4 shards = 1.2 TB storage To reshard this collection, each shard requires 1.2 TB of available storage.
On MongoDB Atlas, you may need to upgrade to the next tier of storage for the resharding operation. You can downgrade once the operation completes.
I/Oキャパシティーが50 % 未満であることを確認します。
CPU 負荷が80 % 未満であることを確認します。
重要
これらの要件はデータベースによって強制されません。 十分なリソースを割り当てられない場合、次の結果が発生する可能性があります。
データベースの容量が不足し、シャットダウンした
パフォーマンスの低下
操作に予想よりも時間がかかる
アプリケーションにトラフィックが少ない期間がある場合は、可能であれば、その時間中にコレクションに対してこの操作を実行します。
現在のシャードキーと新しいシャードキーの両方を使用するには、アプリケーションのクエリを書き直す必要があります。
Tip
アプリケーションがダウンタイムを許容できる場合は、現在のシャードキーと新しいシャードキーの両方を使用するようにアプリケーションのクエリを書き換えるのを避けるために、次の手順を実行します。
アプリケーションを停止します。
新しいシャードキーを使用するようにアプリケーションを書き換えます。
リシャーディングが完了するまで待ちます。 リシャーディング プロセスをモニターするには、
$currentOpパイプライン ステージを使用します。書き換えたアプリケーションをデプロイします。
リシャーディングが完了する前に、クエリフィルターに現在のシャードキーまたは一意のフィールド(
_idなど)が含まれていない場合、次のクエリではエラーが返されます。最適なパフォーマンスを得るには、新しいシャードキーを含むように他のクエリも書き換えることをお勧めします。
再シャーディング操作が完了したら、クエリから古いシャードキーを削除できます。
インデックスのビルドは進行中ではありません。インデックスビルドが実行中どうかを確認するには、
$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のドキュメントを参照してください。
手順
コレクションの再シャーディング操作では、シャードは次のようになります。
ドナーは、シャーディングされたコレクションのチャンクを現在保存しています。
シャードは同時にドナーでも受信者でもあることができます。
コンフィギュレーションサーバーのプライマリは常にリシャーディング コーディネーターであり、リシャーディング操作の各フェーズを開始します。
リシャーディング操作を開始します。
mongosに接続している間に、再シャーディングするコレクションと新しいシャードキーを指定するreshardCollectionコマンドを発行します。
db.adminCommand({ reshardCollection: "<database>.<collection>", key: <shardkey> })
MongoDB は、書込みをブロックする最大秒数を 2 秒に設定し、リシャーディング操作を開始します。
同じシャードキーにリシャーディングするには、forceRedistribution を true に設定します。
db.adminCommand({ reshardCollection: "<database>.<collection>", key: <shardkey>, forceRedistribution: true })
sh.reshardCollection() を使用して、同じキーを持つコレクションを再シャーディングすることもできます。例については、「新しいシャードへのデータの再配布」を参照してください。
リシャーディング操作 を監視します。
リシャーディング操作をモニターするには、 $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>, ... }, ... ]
バランサーを再度有効にします。
バランサーを有効にするには、こちら を参照してください。
動作
リシャーディング操作の最小期間
リシャーディング操作の最小期間は常に 5 分です。
再試行可能な書き込み
リシャーディング前または再シャーディング中に開始された再試行可能な書込みは、コレクションが最大 5 分間再シャーディングされた期間中に、および再シャーディングされた後に再試行できます。 5 分後、書き込みの決定的な結果が見つからず、その後書き込みを再試行しようとすると失敗し、 IncompleteTransactionHistoryエラーが発生します。
エラーケース
Duplicate _id Values
コレクション データの破損を避けるために、 _idの値がグローバルに一意でない場合、リシャーディング操作は失敗します。 _idの値が重複していると、チャンク移行が成功し ない 可能性もあります。 _id値が重複しているドキュメントがある場合は、それぞれから新しいドキュメントにデータをコピーしてから、重複するドキュメントを削除します。