このトピックでは、シャードの追加または削除のために開始されたタスクの進行状況を表示する方法と、タスクが例外によってブロックされているかどうかを確認する方法について説明します。
背景情報
シャードクラスターインスタンスにシャードを追加するタスク、またはインスタンスからシャードを削除するタスクを開始した場合、タスクの送信後も長時間進行中のままになる可能性があります。次の手順では、この問題のトラブルシューティング方法について説明します。
このようなタスクを開始する前に、次の項目について理解しておく必要があります。
ApsaraDB for MongoDB レプリカセットインスタンスとシャードクラスターインスタンスのデプロイメントモード、およびレプリカセットとシャードクラスタアーキテクチャの違い。詳細については、「レプリカセットインスタンス」および「シャードクラスターインスタンス」をご参照ください。
ApsaraDB for MongoDB バランサーの基本的な動作原理。詳細については、「ApsaraDB for MongoDB バランサーを管理する」をご参照ください。
ApsaraDB for MongoDB インスタンスのデータ分散モード。インスタンスデータはチャンクに分散されます。
sh.status()などの、ApsaraDB for MongoDB シャードクラスターインスタンスの一般的な O&M コマンド。mongo シェルや mongosh などの可視化ツールの基本的な使用方法。
タスクの進行状況を確認する
ステップ 1:バランサーが有効になっているかどうかを確認する
シャードノードの追加または削除のために開始されたタスクの場合、データチャンクはバランサーが有効になった後にのみ移行されます。バランサーが無効になっていると、次の問題が発生します。
シャードを追加しているときに、データチャンクを新しいシャードに移行できません。その結果、新しいシャードはビジネストラフィックを処理できません。
シャードを削除しているときに、削除するシャードのデータを移行できません。この場合、シャードを削除するタスクはブロックされます。
データチャンクが想定どおりに移行されるようにするには、バランサーを有効にする必要があります。詳細については、「ApsaraDB for MongoDB バランサーを管理する」をご参照ください。
次のいずれかの方法を使用して、バランサーが有効になっているかどうかを確認できます。
方法 1:
sh.status()コマンドを実行する次の例は、バランサーが有効になっている場合の sh.status() コマンドの出力結果を示しています。
... autosplit: Currently enabled: yes balancer: Currently enabled: yes Currently running: yes Balancer active window is set between 08:30 and 11:30 server local time ...出力に
“Currently enabled: no”と表示されている場合、バランサーは無効になっています。方法 2:
sh.getBalancerState()コマンドを実行するコマンドに対して
trueが返された場合、バランサーは有効になっています。コマンドに対して
falseが返された場合、バランサーは無効になっています。
ステップ 2:バランサーのタイムウィンドウの期間が短くないかを確認する
バランサーは、データチャンクの移行速度を管理します。バランサーは、指定されたタイムウィンドウ内でのみデータチャンクを移行します。指定されたタイムウィンドウ内でデータチャンクが完全に移行されない場合、データ移行タスクは、移行が完了するまで次のタイムウィンドウ内で続行されます。タイムウィンドウの期間が短い場合、シャードの追加または削除タスクの進行が遅延します。バランサーのタイムウィンドウを変更する方法の詳細については、「ApsaraDB for MongoDB バランサーを管理する」をご参照ください。
次のいずれかの方法を使用して、バランサーのタイムウィンドウを確認できます。
方法 1:
sh.status()コマンドを実行する次の例は、コマンドの出力結果を示しています。この例では、バランサーのタイムウィンドウは 08:30 から 11:30(現地時間)までで、合計 3 時間です。
... autosplit: Currently enabled: yes balancer: Currently enabled: yes Currently running: yes Balancer active window is set between 08:30 and 11:30 server local time ...方法 2:
sh.getBalancerWindow()コマンドを実行する次の例は、コマンドの出力結果を示しています。インスタンスに多数のシャードコレクションがある場合、この方法を使用してタイムウィンドウをより直感的に表示できます。
{ "start" : "08:30", "stop" : "11:30" }
ステップ 3:タスクの進行状況を推定するために必要な情報を取得する
MongoDB 6.0 より前のバージョンで使用可能な方法
次の操作は、以下のバージョンで使用できます。
MongoDB 6.0 より前のバージョンを実行しているインスタンス。
リビジョンバージョンが MongoDB 7.0.1(ベンチマークバージョン:6.0.3)より前の MongoDB 6.0 を実行しているインスタンス。インスタンスのマイナーバージョンを表示する方法については、「ApsaraDB for MongoDB のマイナーバージョンのリリースノート」をご参照ください。
タスクを評価する前に、バランサーの操作結果と、移行するシャードコレクションのチャンク情報を取得する必要があります。バランサーの操作結果には、移行されたチャンクの数と移行に失敗したチャンクの数に関する統計が含まれます。
次のいずれかの方法を使用して、上記の情報を取得できます。
方法 1:
sh.status()コマンドの出力結果を表示するsh.status()コマンドの出力結果では、バランサーの最近の操作結果と、移行するシャードテーブルのチャンク情報に焦点を当てる必要があります。次の例は、バランサーの最近の操作結果を示しています。... balancer: Collections with active migrations: <db>.<collection> started at Wed Sep 27 2023 10:25:21 GMT+0800 (CST) Failed balancer rounds in last 5 attempts: 0 Migration Results for the last 24 hours: 300 : Success databases: ...次の例は、移行するシャードコレクションのチャンク情報を示しています。
... databases: ... { "_id" : "<db>", "primary" : "d-xxxxxxxxxxxxxxx3", "partitioned" : true, "version" : { "uuid" : UUID("3409a337-c370-4425-ad72-8b8c6b0abd52"), "lastMod" : 1 } } <db>.<collection> shard key: { "<shard_key>" : "hashed" } unique: false balancing: true chunks: d-xxxxxxxxxxxxxxx1 13630 d-xxxxxxxxxxxxxxx2 13629 d-xxxxxxxxxxxxxxx3 13652 d-xxxxxxxxxxxxxxx4 13630 d-xxxxxxxxxxxxxxx5 3719 too many chunks to print, use verbose if you want to force print ...上記の例では、d-xxxxxxxxxxxxxxx5 は追加されたシャードを示しています。パーティションテーブルが配置されているデータベースで
getShardDistributionコマンドを実行して、データチャンクの分散に関する情報を取得することもできます。サンプルコード:use <db> db.<collection>.getShardDistribution()方法 2:config データベースから関連情報を直接読み取る
チャンクの統計をクエリし、シャードごとに集計します。サンプルコード:
db.getSiblingDB("config").chunks.aggregate([{$group: {_id: "$shard", count: {$sum: 1}}}])指定されたシャードのチャンクをクエリし、名前空間ごとに集計します。サンプルコード:
db.getSiblingDB("config").chunks.aggregate([{$match: {shard: "d-xxxxxxxxxxxxxx"}},{$group: {_id: "$ns", count: {$sum: 1}}}])前日に指定されたシャードに移行されたチャンクの数をクエリします。サンプルコード:
// details.to フィールドを、チャンクの移行先となるシャードとして指定します。 // time フィールドを ISODate タイプの期間として指定します。 db.getSiblingDB("config").changelog.find({"what" : "moveChunk.commit", "details.to" : "d-xxxxxxxxxxxxx","time" : {"$gte": ISODate("2023-09-26T00:00:00")}}).count()
MongoDB 6.0 以降のバージョンで使用可能な方法
次の操作は、以下のバージョンで使用できます。
MongoDB 6.0 以降のバージョンを実行しているインスタンス。
リビジョンバージョンが MongoDB 7.0.1(ベンチマークバージョン:6.0.3)以降の MongoDB 6.0 を実行しているインスタンス。インスタンスのマイナーバージョンを表示する方法については、「ApsaraDB for MongoDB のマイナーバージョンのリリースノート」をご参照ください。
タスクを評価する前に、シャード間のデータ分散に焦点を当てる必要があります。sh.status() コマンドによって返される出力は引き続き参照として使用できます。ただし、出力を取得した後は、各シャードのチャンク数の不均一性ではなく、各シャードのデータ分散に注意を払う必要があります。
シャードコレクションのデータ分散と均一性を取得する。
次の図に示すように、
getShardDistributionコマンドを実行して、シャードコレクションのデータ分散を取得し、データの均一性に焦点を当てることをお勧めします。
次のコマンドを実行して、ドキュメントの数と合計サイズ、および孤立ドキュメントの数など、より詳細な分散を取得することもできます。
db.getSiblingDB("admin").aggregate( [{ $shardedDataDistribution: { } },{ $match: { "ns": "<db>.<collection>" } }] ).pretty()次の例は、上記のコマンドの出力結果を示しています。出力は、シャード間でデータが著しく不均一であることを示しています。
{ "ns" : "<db>.<collection>", "shards" : [ { "shardName" : "d-xxxxxxxxxxxxxxx1", "numOrphanedDocs" : 0, "numOwnedDocuments" : 504298920, "ownedSizeBytes" : NumberLong("833101815840"), "orphanedSizeBytes" : 0 }, { "shardName" : "d-xxxxxxxxxxxxxxx2", "numOrphanedDocs" : 0, "numOwnedDocuments" : 250283901, "ownedSizeBytes" : NumberLong("409714745937"), "orphanedSizeBytes" : 0 }, { "shardName" : "d-xxxxxxxxxxxxxxx3", "numOrphanedDocs" : 0, "numOwnedDocuments" : 109098088, "ownedSizeBytes" : NumberLong("178157177704"), "orphanedSizeBytes" : 0 }, { "shardName" : "d-xxxxxxxxxxxxxxx4", "numOrphanedDocs" : 0, "numOwnedDocuments" : 382018055, "ownedSizeBytes" : NumberLong("630329790750"), "orphanedSizeBytes" : 0 } ] }出力は、次の項目も示しています。1. 上記のコマンドを実行したインスタンスには、4 つのシャードが含まれています。2. インスタンス内の
<db>.<collection>という名前のシャードコレクションのデータ量は約 2051303530231 バイト(833101815840 + 409714745937 + 178157177704 + 630329790750)で、これは 1910.4 GB に相当します。前日に正常に移行されたデータ量を表示する。
次のコマンドを実行します。
pipeline = [ { '$match': { 'what': 'moveChunk.commit', } }, { '$group': { '_id': { 'date': { '$dateToString': { 'format': '%Y-%m-%d', 'date': '$time'} }, }, 'chunks_moved': { '$sum': 1 }, 'docs_moved': { '$sum': '$details.counts.cloned' }, 'bytes_moved': { '$sum': '$details.counts.clonedBytes' }, } }, { '$sort': { '_id.date': -1} }, ] db.getSiblingDB("config").changelog.aggregate(pipeline)次の図は、上記のコマンドの出力結果を示しています。

出力は、
2024-09-21に 183117965820 バイトが正常に移行されたことを示しており、これは 170.5 GB に相当します。
ステップ 4:タスクの進行状況と完了時間を推定する
MongoDB 6.0 より前のバージョンで使用可能な方法
次の操作は、以下のバージョンで使用できます。
MongoDB 6.0 より前のバージョンを実行しているインスタンス。
リビジョンバージョンが MongoDB 7.0.1(ベンチマークバージョン:6.0.3)より前の MongoDB 6.0 を実行しているインスタンス。インスタンスのマイナーバージョンを表示する方法については、「ApsaraDB for MongoDB のマイナーバージョンのリリースノート」をご参照ください。
シャードコレクションから移行されたチャンクの数と、現在のシャードコレクションのデータ分散を取得したら、タスクの全体的な進行状況と予想される完了時間を推定できます。
シャードを追加するとします。シャードが追加される前は、チャンクの総数は変更されません。また、シャードの数も変更されないため、シャードを追加または削除するタスクは開始されません。シャードを追加している間、ビジネスワークロードは一定のままで、バランサーに関連するパラメーターはデフォルト値に設定されます。ステップ 3 の「MongoDB 6.0 より前のバージョンで使用可能な方法」で説明されている最初の例を使用します。この例は、次の項目を示しています。
5 つのシャードが追加されます。
バランサーのタイムウィンドウ内で 300 個のチャンクが移行されます。
<db>.<collection>という名前のシャードコレクションには、58,260 個のチャンクが含まれています。チャンクの数は、次の式に基づいて計算されます。13,630 + 13,629 + 13,652 + 13,630 + 3,719 = 58,260。
上記の結果に基づいて、次の値を計算できます。
チャンクがシャードに均等に分散されている場合、各シャードのチャンク数は 11,652(58,260/5 = 11,652)です。
現在の移行速度に基づくと、移行の完了にはさらに 26.4 日かかります。日数は、次の式に基づいて計算されます。(11,652 - 3,719)/300 ≈ 26.4。
シャードを追加するタスクの進行状況は 32%(3,719/11,652 = 32%)です。
実際のシナリオでは、データがインスタンスに継続的に書き込まれ、チャンクの分割が発生するため、チャンクの総数は増加します。上記の仮定は理想的な条件です。タスクの完了に必要な実際の時間は、より長くなる可能性があります。
MongoDB 6.0 以降のバージョンで使用可能な方法
次の操作は、以下のバージョンで使用できます。
MongoDB 6.0 以降のバージョンを実行しているインスタンス。
リビジョンバージョンが MongoDB 7.0.1(ベンチマークバージョン:6.0.3)以降の MongoDB 6.0 を実行しているインスタンス。インスタンスのマイナーバージョンを表示する方法については、「ApsaraDB for MongoDB のマイナーバージョンのリリースノート」をご参照ください。
シャードクラスターインスタンス内の 1 つのコレクションのみをバランスする必要があるとします。ステップ 3 の「MongoDB 6.0 以降のバージョンで使用可能な方法」で説明されている最初の例を使用します。この例は、次の項目を示しています。
4 つのシャードが追加されます。
2024-09-21に 183117965820 バイトが正常に移行され、これは 170.5 GB に相当します。<db>.<collection>という名前のシャードコレクションのデータ量は約 2051303530231 バイト(833101815840 + 409714745937 + 178157177704 + 630329790750)で、これは 1910.4 GB に相当します。
上記の結果に基づいて、次の値を計算できます。
シャード間でデータバランスが達成されると、各シャードのデータ量は約 512825882557.75 バイトで、これは 477.6 GB に相当します。
シャード間でデータバランスを達成するには、シャード間で合計 875559682949 バイトを移行する必要があり、これは 815.4 GB に相当します。各シャードからの具体的なデータ移行:
シャード 1 から移行されるデータ量は 320275933282.25 バイト(833101815840 - 512825882557.75)です。
シャード 2 から移行されるデータ量は 103111136620.75 バイト(409714745937 - 512825882557.75)です。
シャード 3 から移行されるデータ量は 334668704853.75 バイト(178157177704 - 512825882557.75)です。
シャード 4 から移行されるデータ量は 117503908192.25 バイト(630329790750 - 512825882557.75)です。
(320275933282.25 + 103111136620.75 + 334668704853.75 + 117503908192.25 = 875559682949)
現在の移行速度では、データバランスに到達するまでに約 4.8 日(815.4 GB/1 日あたり 170.5 GB)かかります。
ステップ 5:シャードを削除しているときにタスクがブロックされているかどうかを確認する
シャードを削除するために開始されたタスクがブロックされている場合、sh.status() コマンドの出力結果には、前の期間にチャンクが正常に移行されたことを示すメッセージが含まれず、削除されるシャードから一部のチャンクが移行されません。この場合、タスクは完了せず、ApsaraDB for MongoDB コンソールでインスタンスに対して実行される O&M 操作に影響します。
次の例は、sh.status() コマンドの出力結果を示しています。

上記の問題は、ジャンボチャンクが原因である可能性があります。これは、シャードの削除の進行を妨げます。次のコマンドを使用して、ジャンボチャンクが存在するかどうかを確認できます。
db.getSiblingDB("config").chunks.aggregate([{$match: {shard: "d-xxxxxxxxxxxxxx", jumbo:true}},{$group: {_id: "$ns", count: {$sum: 1}}}])ほとんどの場合、ジャンボチャンクの発生は、不適切な、または不適切に選択されたシャードキー設計などの要因に起因する可能性があり、ホットキーの存在が含まれる場合があります。クライアントでジャンボチャンクの問題をトラブルシューティングするには、次のいずれかの方法を使用できます。
インスタンスのメジャーエンジンバージョンが MongoDB 4.4 の場合、refineCollectionShardKey コマンドを実行して、シャードキーの設計を最適化できます。ジャンボチャンクに関連する問題に対処するには、元のシャードキーに接尾辞を追加して、キーのカーディナリティを増やすことができます。
インスタンスのメジャーエンジンバージョンが MongoDB 5.0 以降の場合、reshardCollection コマンドを実行して、新しいシャードキーに基づいて指定されたシャードコレクションを再シャードできます。詳細については、「コレクションの再シャード」をご参照ください。
一部のデータを削除できると確信している場合は、対応するジャンボチャンクからデータを削除できます。これにより、ジャンボチャンクのサイズが小さくなります。一部のデータが削除されると、ジャンボチャンクは通常のチャンクサイズに縮小され、バランサーによって移動されます。
chunkSizeパラメーターの値を増やして、ジャンボチャンクを決定する条件を変更できます。Alibaba Cloud テクニカルサポートからの提案に基づいて操作を実行することをお勧めします。
シャードの追加または削除のために開始されたタスクの進行を加速する
シャードの追加または削除の全体的なプロセスを迅速化するには、次のいずれかの方法を使用できます。
バランサーのタイムウィンドウを増やします。ただし、チャンクの移行はサービスに追加の負荷をもたらす可能性があり、ビジネス運用のパフォーマンスに影響を与える可能性があります。したがって、タイムウィンドウを変更する前にリスクを評価することをお勧めします。タイムウィンドウを変更する方法の詳細については、「ApsaraDB for MongoDB バランサーを管理する」をご参照ください。
シャードクラスターインスタンスの setParameter.chunkMigrationConcurrency パラメーターの値を調整して、同時に移行されるチャンクの数を変更します。パラメーターの使用方法の詳細については、「シャードクラスターインスタンス(シャード専用のパラメーター)」をご参照ください。
オフピーク時に
moveChunk操作を実行します。詳細については、「sh.moveChunk()」をご参照ください。サンプルコード:sh.moveChunk("<db>.<collection>", {"<shard_key>": <value>}, "d-xxxxxxxxxxxxx") // 例: sh.moveChunk("records.people", { zipcode: "53187" }, "shard0019")- チケットを送信する して、テクニカルサポートに連絡して関連するカーネルパラメーターを変更します。