シャーディングされたクラスター上のローリングインデックス構築
インデックスビルドはシャーディングされたクラスターのパフォーマンスに影響を与える可能性があります。 デフォルトでは、MongoDB はデータを保持するすべてのレプリカセット メンバーにインデックスを同時に構築します。 シャーディングされたクラスターでのインデックスビルドは、インデックスが作成されるコレクションのデータを含むシャードでのみ行われます。 インデックス ビルドによるパフォーマンスの低下を許容できないワークロードの場合は、次の手順でローリング方式でインデックスをビルドすることを検討してください。
ローリング処理によるインデックスビルドでは、一度に最大 1 つのシャード レプリカセットメンバーを使用します。セカンダリ メンバーから始まり、そのメンバーにスタンドアロンとしてインデックスがビルドされます。 ローリング処理によるインデックスビルドには、シャードごとに少なくとも 1 回のレプリカセット選挙が必要です。
注意
Atlas でのインデックスの作成の詳細については、Atlas ドキュメントのインデックス マネジメントのページを参照してください。
Considerations
Unique Indexes
以下の手順を使用して 一意なインデックスを作成するには、以下の手順を使用して、この手順の実行中にコレクションへのすべての書き込みを停止する必要があります。
この手順の実行中にコレクションへのすべての書き込みを停止できない場合は、このページの手順を使用しないでください。 db.collection.createIndex()
代わりに、シャーディングされたクラスターのmongos
で を発行して、コレクションに一意のインデックスをビルドします。
Oplog サイズ
インデックス作成または再インデックス作成操作が遅れることなく完了できるように、oplog が十分に大きいことを確認してください。詳細については、oplog のサイズ設定に関するその他の情報を参照してください。
始める前に
- 一意なインデックスの構築
以下の手順を使用してユニークインデックスを作成するには、インデックス構築中にコレクションへのすべての書き込みを停止する必要があります。そうしないと、レプリカセット ノード間でデータの不整合が生じる可能性があります。 コレクションへのすべての書き込みを停止できない場合は、ユニークインデックスを作成する以下の手順を使用しないでください。
警告
コレクションへのすべての書き込みを停止できない場合は、一意なインデックスを作成する以下の手順を使用しないでください。
インデックスを作成する前に、コレクション内のドキュメントがどれもインデックス制約に違反していないことを検証します。 コレクションがシャード全体に分散されており、シャードに重複ドキュメントを含むチャンクが含まれている場合、インデックスの作成操作は、重複のないシャードでは成功するものの、重複のあるシャードでは成功しない可能性があります。 シャード間で不整合なインデックスが残らないようにするには、 から
db.collection.dropIndex()
mongos
を発行して、コレクションからインデックスを削除します。
MongoDB 8.0以降では、 directShardOperations
ロールを使用して、シャードに対してコマンドを直接実行する必要があるメンテナンス操作を実行できます。
警告
directShardOperations
ロールを使用して コマンドを実行すると、クラスターが正しく動作しなくなり、データが破損する可能性があります。 directShardOperations
ロールは、メンテナンス目的で、または MongoDB サポートのガイダンスに必ず従う必要があります。 メンテナンス操作を実行したら、 directShardOperations
ロールの使用を停止します。
手順
重要
ローリング方式でインデックスを構築する以下の手順は、レプリカセットの配置ではなく、シャーディングされたクラスターの配置に適用されます。 レプリカセットの手順については、代わりに「レプリカセット上のローリングインデックスの構築 」を参照してください。
A. バランサーを停止する
mongosh
mongos
シャーディングされたクラスター内のsh.stopBalancer()
インスタンスに接続し、 を実行してバランサーを無効にします。 [1 ]
sh.stopBalancer()
注意
移行が進行中の場合、システムは進行中の移行を完了してから、バランサーを停止します。
バランサーが無効になっていることを確認するには、 sh.getBalancerState()
を実行します。バランサーが無効になっている場合は false を返します。
sh.getBalancerState()
[1] | MongoDB 6.0.3以降、 自動チャンク分割は実行されません。 これはバランシング ポリシーの改善によるものです。 自動分割コマンドは引き続き存在しますが、操作は実行されません6.0.3より前のバージョンの MongoDB では、 sh.stopBalancer() は、シャーディングされたクラスターの自動分割も無効にします。 |
B. コレクションのディストリビューションを決定する
mongosh
に接続されている から、コレクションの古いディストリビューション情報が返されないように、その のキャッシュされたルーティングmongos
mongos
テーブルを更新してください。更新したら、インデックスを構築するコレクションに対してdb.collection.getShardDistribution()
を実行します。
たとえば、 test
データベースのrecords
コレクションに昇順のインデックスを作成するには、次のようにします。
db.adminCommand( { flushRouterConfig: "test.records" } ); db.records.getShardDistribution();
メソッドは シャード ディストリビューションを出力します。 たとえば、3 つのシャードshardA
、 shardB
、 shardC
を持つシャーディングされたクラスターを考えてみます。 db.collection.getShardDistribution()
は次の結果を返します。
Shard shardA at shardA/s1-mongo1.example.net:27018,s1-mongo2.example.net:27018,s1-mongo3.example.net:27018 data : 1KiB docs : 50 chunks : 1 estimated data per chunk : 1KiB estimated docs per chunk : 50 Shard shardC at shardC/s3-mongo1.example.net:27018,s3-mongo2.example.net:27018,s3-mongo3.example.net:27018 data : 1KiB docs : 50 chunks : 1 estimated data per chunk : 1KiB estimated docs per chunk : 50 Totals data : 3KiB docs : 100 chunks : 2 Shard shardA contains 50% data, 50% docs in cluster, avg obj size on shard : 40B Shard shardC contains 50% data, 50% docs in cluster, avg obj size on shard : 40B
出力から、 shardA
とshardC
でtest.records
のインデックスのみをビルドします。
C. コレクション チャンクを含むシャードでインデックスを構築する
コレクションのチャンクを含む各シャードに対して、シャードにインデックスを構築する手順に従ってください。
C1。 1 つのセカンダリを停止し、スタンドアロンとして再起動
影響を受けるシャードの場合は、そのセカンダリの 1 つに関連付けられているmongod
プロセスを停止します。 次の設定更新を行った後、再起動します。
構成ファイルを使用している場合は、次の構成を更新します。
replication.replSetName
オプションをコメントアウトします。sharding.clusterRole
オプションをコメントアウトします。セクションでパラメータ
skipShardingConfigurationChecks
をtrue
setParameter
に設定します。setParameter
セクションでパラメータdisableLogicalSessionCacheRefresh
をtrue
に設定します。
たとえば、シャード レプリカセット ノードの場合、更新された構成ファイルには次の例のような内容が含まれます。
net: bindIp: localhost,<hostname(s)|ip address(es)> port: 27218 # port: 27018 #replication: # replSetName: shardA #sharding: # clusterRole: shardsvr setParameter: skipShardingConfigurationChecks: true disableLogicalSessionCacheRefresh: true
そして再起動します。
mongod --config <path/To/ConfigFile>
その他の設定(例: storage.dbPath
など)は同じままです。
コマンドライン オプションを使用する場合は、次の構成更新を行います。
シャード ノードの場合は
--shardsvr
を削除し、コンフィギュレーションサーバー ノードの場合は--configsvr
を削除します。オプションでパラメータ
skipShardingConfigurationChecks
をtrue
--setParameter
に設定します。--setParameter
オプションでパラメータdisableLogicalSessionCacheRefresh
をtrue
に設定します。
たとえば、 --replSet
と--shardsvr
オプションを使用せずにシャード レプリカセット ノードを再起動します。 新しいポート番号を指定し、 skipShardingConfigurationChecks
} パラメーターとdisableLogicalSessionCacheRefresh
パラメーターの両方を true に設定します。
mongod --port 27218 --setParameter skipShardingConfigurationChecks=true --setParameter disableLogicalSessionCacheRefresh=true
その他の設定(例: --dbpath
など)は同じままです。
[2] | (1、2)mongod を別のポートで実行することで、インデックスの構築中にレプリカセットの他のノードと全クライアントがそのノードにコンタクトしないようにします。 |
C2。インデックスを構築
新しいポートでスタンドアロンとして実行されている mongod
インスタンスに直接接続し、このインスタンスの新しいインデックスを作成します。
たとえば、 mongosh
を インスタンスに接続し、 db.collection.createIndex()
メソッドを使用してrecords
コレクションのusername
フィールドに昇順のインデックスを作成します。
db.records.createIndex( { username: 1 } )
C3 。プログラムmongod
をレプリカセット メンバーとして再起動する
インデックスのビルドが完了したら、 mongod
インスタンスをシャットダウンします。 スタンドアロンとして起動する際に行った構成変更を元に戻し、再起動します。
重要
skipShardingConfigurationChecks
パラメータとdisableLogicalSessionCacheRefresh
パラメータは必ず削除してください。
たとえば、レプリカセットのシャード ノードを再起動するには、次のようにします。
構成ファイルを使用している場合:
元のポート番号に戻します。
replication.replSetName
のコメントアウトを外します。sharding.clusterRole
のコメントアウトを外します。セクションでパラメータ
skipShardingConfigurationChecks
setParameter
を削除します。setParameter
セクションのパラメータdisableLogicalSessionCacheRefresh
を削除します。
net: bindIp: localhost,<hostname(s)|ip address(es)> port: 27018 replication: replSetName: shardA sharding: clusterRole: shardsvr
その他の設定(例: storage.dbPath
など)は同じままです。
そして再起動します。
mongod --config <path/To/ConfigFile>
コマンドライン オプションを使用している場合は、次のようになります。
元のポート番号に戻します。
シャード ノードの場合は
--shardsvr
を含め、コンフィギュレーションサーバー ノードの場合は--configsvr
を含めます。Remove parameter
skipShardingConfigurationChecks
.Remove parameter
disableLogicalSessionCacheRefresh
.
以下に例を挙げます。
mongod --port 27018 --replSet shardA --shardsvr
その他の設定(例: --dbpath
など)は同じままです。
レプリケーションがこのノードにキャッチアップすることを許可します。
C4。シャードの残りのセカンダリにこの手順を繰り返す
メンバーがセットの他のメンバーに追いつくと、シャードの残りのセカンダリ メンバーに対して、一度に 1 つのメンバーに対してこの手順を繰り返します。
C5。プライマリでのインデックスの構築
シャードのすべてのセカンダリに新しいインデックスが作成されたら、シャードのプライマリをステップダウンさせ、上記の手順を使用してスタンドアロンとして再起動し、以前のプライマリにインデックスを構築します。
rs.stepDown()
mongosh
プライマリを降格するには、 で メソッドを使用します。ステップダウンが成功すると、現在のプライマリがセカンダリになり、レプリカセット ノードによって新しいプライマリが選択されます。
D. 影響を受ける他のシャードに繰り返し
シャードのインデックスの作成が終了したら、 C を繰り返します。影響を受ける他のシャード用に、コレクション チャンクを含むシャードでインデックスを構築する
E. バランサーを再起動する
影響を受けるシャードのローリング インデックスのビルドが完了したら、バランサーを再起動します。
mongosh
mongos
シャーディングされたクラスター内の インスタンスに接続し、sh.startBalancer()
を実行します: [3 ]
sh.startBalancer()
[3] | MongoDB 6.0.3以降、 自動チャンク分割は実行されません。 これはバランシング ポリシーの改善によるものです。 自動分割コマンドは引き続き存在しますが、操作は実行されません6.0.3より前のバージョンの MongoDB では、 sh.startBalancer() は、シャーディングされたクラスターの自動分割も有効にします。 |
詳細情報
コレクションのチャンクを含む各シャードにまったく同じインデックス(インデックスオプションを含む)がない場合、シャーディングされたコレクションのインデックスには一貫性がありません。通常の操作では一貫性のないインデックスは発生しないはずですが、次のような一貫性のないインデックスが発生する可能性があります。
ユーザーが
unique
キー制約を使用してインデックスを作成していて、1 つのシャードに重複ドキュメントを含むチャンクが含まれている場合。このような場合、インデックスの作成操作は、重複のないシャードでは成功するものの、重複のあるシャードでは成功しない可能性があります。ユーザーが複数のシャードにわたってインデックスを ローリング処理で作成しているが、関連付けられたシャードのインデックス作成に失敗した 、 または 異なる仕様で誤ったインデックスをビルドした場合 。
コンフィギュレーションサーバーのプライマリは、シャーディングされたコレクションのシャード間でのインデックスの不整合を定期的にチェックします。 これらの定期的チェックを構成するには、 enableShardedIndexConsistencyCheck
とshardedIndexConsistencyCheckIntervalMS
を参照してください。
コマンドserverStatus
は、構成サーバーのプライマリで実行された場合にインデックスの不整合を報告するフィールド shardedIndexConsistency
を返します。
シャーディングされたコレクションに一貫性のないインデックスがないかどうかを確認するには、「シャード間で一貫性のないインデックスを検索する」を参照してください。