Docs Menu

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

バージョン 5.0 で追加

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

注意

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

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

  • アプリケーションは、再シャーディング中のコレクションが書込みをブロックする期間を2 秒許容できます。 書込み (write) がブロックされている期間中、アプリケーションのレイテンシが増加します。 ワークロードがこの要件を許容できない場合は、代わりにシャードキーの改良を検討してください

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

    • 使用可能なストレージ容量: コレクションを分散する各シャードで使用可能なストレージ容量が、少なくとも再シャーディングするコレクションのサイズとその合計インデックス サイズの 2 倍で、シャードの数で割られていることを確認してください。

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

      たとえば、 2 TB のデータを含み、4 つのシャードに分散された400 GB インデックスを持つコレクションを考えてみましょう。 このコレクションでリシャーディング操作を実行するには、各シャードに1.2が必要です TB の使用可能なストレージ。

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

      ストレージ要件を満たすには、再シャーディング操作中に 1 つ上のストレージ階層にアップグレードする必要がある場合があります。 操作が完了したらスケールダウンできます。

    • I/O: I/O 容量が 50% 未満であることを確認します。

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

    重要

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

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

    • パフォーマンスの低下

    • リシャーディング操作に予想よりも時間がかかる

    アプリケーションにトラフィックが少ない期間がある場合は、可能であれば、その時間中にコレクションを再シャーディングします。

  • 現在のシャードキーと新しいシャードキーの両方を使用するには、アプリケーションのクエリを書き直す必要があります。

    Tip

    アプリケーションがダウンタイムを許容できる場合は、現在のシャードキーと新しいシャードキーの両方を使用するようにアプリケーションのクエリを書き換えるのを避けるために、次の手順を実行します。

    1. アプリケーションを停止します。

    2. 新しいシャードキーを使用するようにアプリケーションを書き換えます。

    3. リシャーディングが完了するまで待ちます。 リシャーディング プロセスをモニターするには、 $currentOpパイプライン ステージを使用します。

    4. 書き換えたアプリケーションをデプロイします。

    リシャーディングが完了する前に、クエリフィルターに現在のシャードキーまたは一意のフィールド( _idなど)が含まれていない場合、次のクエリではエラーが返されます。

    最適なパフォーマンスを得るには、新しいシャードキーを含むように他のクエリも書き換えることをお勧めします。

    再シャーディング操作が完了したら、クエリから古いシャードキーを削除できます。

  • インデックスのビルドは進行中ではありません。 実行中のインデックス ビルドを確認するには、 db.currentOp()を使用します。

    db.adminCommand(
    {
    currentOp: true,
    $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のドキュメントを参照してください。

重要

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

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

シャードは同時にドナーでも受信者でもあることができます。 ゾーン を使用する場合を除き、ドナー シャードのセットは受信者シャードと同じです。

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

1

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

2

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

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

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

3

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

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

注意

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

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

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

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

    次以降:

    • MongoDB 5.0 および MongoDB 6.1 より前では、 remainingOperationTimeEstimatedSecsは 再シャーディング操作 中に受信者シャードでのみ使用できます。

    • MongoDB 6.1、 remainingOperationTimeEstimatedSecsは、リシャーディング操作中にコーディネーターで使用することもできます。

    リシャーディング操作では、これらのフェーズを順番に実行されます。

    1. クローン フェーズは、現在のコレクション データを複製します。

    2. キャッチアップ フェーズは、保留中の書込み (write) 操作をリシャーディングされたコレクションに適用します。

    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エラーが発生します。

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