Tous les produits
Search
Centre de documentation

ApsaraDB for MongoDB:Comment vérifier la progression de l'ajout ou de la suppression de nœuds shard

Dernière mise à jour :Aug 20, 2026

Cette rubrique explique comment surveiller la progression des tâches d'ajout ou de suppression de nœuds shard et identifier les anomalies susceptibles de bloquer ces opérations.

Informations générales

Après avoir ajouté ou supprimé des nœuds shard dans une instance de cluster fragmenté, la tâche peut rester incomplète pendant une période prolongée. Les sections suivantes expliquent comment résoudre ce problème.

Avant de commencer, assurez-vous de maîtriser les concepts suivants :

  • Les modes de déploiement des instances MongoDB en replica set et en cluster fragmenté, ainsi que les différences entre ces architectures. Pour plus d'informations, consultez les rubriques Architecture en replica set et Architecture de cluster fragmenté.

  • Le fonctionnement du Balancer MongoDB. Pour plus de détails, reportez-vous à la rubrique Gérer le Balancer MongoDB.

  • Le partitionnement des données par MongoDB. MongoDB divise les données en chunks.

  • Les commandes d'exploitation et de maintenance courantes pour les instances de cluster fragmenté MongoDB, telles que sh.status().

  • L'utilisation de mongo shell, mongosh ou d'autres outils de visualisation.

Vérifier la progression de la tâche

Étape 1 : Vérifier si le Balancer est activé

La migration des chunks lors de l'ajout ou de la suppression de shards dépend du Balancer. Si le Balancer est désactivé, les problèmes suivants surviennent :

  • Lors de l'ajout d'un nœud shard : les données des chunks ne peuvent pas migrer vers le nouveau nœud shard, et ce dernier ne peut pas traiter le trafic de service.

  • Lors de la suppression d'un nœud shard : les chunks présents sur le shard cible ne peuvent pas être migrés ailleurs, ce qui bloque la tâche de suppression.

Activez le Balancer pour garantir une migration normale des chunks. Pour obtenir des instructions, consultez la rubrique Gérer le Balancer MongoDB.

Utilisez l'une des méthodes suivantes pour vérifier si le Balancer est activé :

  • Méthode 1 : Exécutez la commande sh.status().

    Si le Balancer est activé, la sortie ressemble à l'exemple suivant.

    ...
      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
    ...

    Si la sortie affiche “Currently enabled: no”, le Balancer est désactivé.

  • Méthode 2 : Exécutez la commande sh.getBalancerState().

    • Si la commande renvoie true, le Balancer est activé.

    • Si la commande renvoie false, le Balancer est désactivé.

Étape 2 : Vérifier si la fenêtre du Balancer est trop courte

Le Balancer contrôle la vitesse de migration des chunks et n'effectue les migrations que durant sa fenêtre active. Si la migration ne se termine pas dans la fenêtre actuelle, elle reprend lors de la fenêtre suivante jusqu'à achèvement. Une fenêtre courte peut ralentir les tâches d'ajout ou de suppression de shards. Pour ajuster la fenêtre du Balancer, consultez la rubrique Gérer le Balancer MongoDB.

Utilisez l'une des méthodes suivantes pour vérifier la fenêtre du Balancer :

  • Méthode 1 : Exécutez la commande sh.status().

    L'exemple suivant montre une fenêtre du Balancer allant de 08:30 à 11:30 (heure locale du serveur), soit un total de 3 heures.

    ...
      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
    ...
  • Méthode 2 : Exécutez la commande sh.getBalancerWindow().

    L'exemple suivant affiche clairement l'horaire de la fenêtre, ce qui s'avère particulièrement utile lorsque de nombreuses collections fragmentées existent.

    { "start" : "08:30", "stop" : "11:30" }

Étape 3 : Recueillir les informations nécessaires pour estimer la progression de la tâche

Pour les versions MongoDB antérieures à 6,0

Remarque

Cette section s'applique aux versions suivantes :

  • Instances MongoDB de version antérieure à 6,0.

  • Instances MongoDB 6.0 dont la version mineure du moteur est antérieure à 7.0.1 (version de base 6.0.3). Pour vérifier votre version mineure du moteur, consultez le Guide des versions mineures MongoDB.

Avant d'estimer la progression de la tâche, obtenez les statistiques d'exécution du Balancer (nombre de succès et d'échecs) ainsi que les informations sur les chunks des collections fragmentées en attente de migration.

Vous pouvez obtenir les résultats d'exécution du Balancer et les informations sur les chunks des tables fragmentées en attente de migration à l'aide des deux méthodes suivantes :

  • Méthode 1 : Utilisez la sortie de la commande sh.status().

    Concentrez-vous sur deux parties de la sortie de sh.status(). La première partie affiche les résultats récents du Balancer, comme dans cet exemple.

    ...
      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:
    ...

    La seconde partie présente les détails des chunks pour les collections fragmentées, comme illustré ci-dessous.

    ...
    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
    ...

    Dans cet exemple, « d-xxxxxxxxxxxxxxx5 » correspond au nœud shard nouvellement ajouté. Vous pouvez également exécuter la commande getShardDistribution dans la base de données contenant la collection fragmentée pour obtenir les détails de la distribution des chunks, comme indiqué ci-dessous.

    use <db>
    db.<collection>.getShardDistribution()
  • Méthode 2 : Lisez directement les données pertinentes depuis la base de données config.

    Consultez les statistiques des chunks agrégées par shard comme suit.

    db.getSiblingDB("config").chunks.aggregate([{$group: {_id: "$shard", count: {$sum: 1}}}])

    Pour afficher les chunks sur un shard spécifique regroupés par namespace, exécutez la commande suivante.

    db.getSiblingDB("config").chunks.aggregate([{$match: {shard: "d-xxxxxxxxxxxxxx"}},{$group: {_id: "$ns", count: {$sum: 1}}}])

    Pour compter les chunks migrés avec succès vers un nœud shard spécifique au cours des dernières 24 heures, exécutez la commande suivante.

    // details.to specifies the destination shard for chunk migration
    // Use ISODate to define the time range in the time field
    db.getSiblingDB("config").changelog.find({"what" : "moveChunk.commit", "details.to" : "d-xxxxxxxxxxxxx","time" : {"$gte": ISODate("2023-09-26T00:00:00")}}).count()

Pour les versions MongoDB 6.0 et ultérieures

Remarque

Cette section s'applique aux versions suivantes :

  • Instances MongoDB version 6.0 et ultérieures.

  • Instances MongoDB 6.0 dont la version mineure du moteur est 7.0.1 (version de base 6.0.3) ou ultérieure. Pour vérifier votre version mineure du moteur, consultez le Guide des versions mineures MongoDB.

Avant d'estimer la progression de la tâche, concentrez-vous sur la distribution des données entre les shards. Vous pouvez toujours utiliser la sortie de sh.status() comme référence, mais déplacez votre attention du nombre inégal de chunks vers la distribution réelle du volume de données.

  • Obtenez la distribution des collections fragmentées et les informations sur l'équilibre des données.

    Utilisez la commande getShardDistribution pour obtenir les détails de la distribution et vous concentrer sur l'équilibre des données. Exemple :

    mongos> db.xxx.getShardDistribution()
    Shard d-xxx at xxx
     data : 379.26MiB docs : 8277367 chunks : 1
     estimated data per chunk : 379.26MiB
     estimated docs per chunk : 8277367
    Shard d-xxx at xxx
     data : 379.11MiB docs : 8272852 chunks : 1
     estimated data per chunk : 379.11MiB
     estimated docs per chunk : 8272852
    Shard d-xxx at xxx
     data : 379.18MiB docs : 8275108 chunks : 1
     estimated data per chunk : 379.18MiB
     estimated docs per chunk : 8275108
    Totals
     data : 1.11GiB docs : 24825327 chunks : 3
     Shard d-xxx contains 33.34% data, 33.34% docs in cluster, avg obj size on shard : 48B
     Shard d-xxx contains 33.32% data, 33.32% docs in cluster, avg obj size on shard : 48B
     Shard d-xxx contains 33.33% data, 33.33% docs in cluster, avg obj size on shard : 48B

    Vous pouvez également exécuter la commande suivante pour obtenir des informations de distribution plus détaillées (incluant le nombre de documents, la taille totale, le nombre de documents orphelins et la taille des orphelins) :

    db.getSiblingDB("admin").aggregate( [{ $shardedDataDistribution: { } },{ $match: { "ns": "<db>.<collection>" } }] ).pretty()

    La sortie d'exemple suivante met en évidence un déséquilibre notable des données entre les shards.

    {
            "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
                    }
              ]
    }

    À partir de cette sortie, vous pouvez déterminer que l'instance dispose de 4 nœuds shard et que le volume total de données pour la collection fragmentée <db>.<collection> est d'environ 2 051 303 530 231 octets (833 101 815 840 + 409 714 745 937 + 178 157 177 704 + 630 329 790 750 = 2 051 303 530 231), soit environ 1 910,4 Go.

  • Consultez le volume de données migré avec succès au cours de la journée écoulée.

    Exécutez la requête suivante :

    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)

    Exemple de sortie :

    mongos> db.getSiblingDB("config").changelog.aggregate(pipeline)
    { "_id" : { "date" : "2024-09-24" }, "chunks_moved" : 91, "docs_moved" : NumberLong(33071040), "bytes_moved" : NumberLong("11532786734") }
    { "_id" : { "date" : "2024-09-23" }, "chunks_moved" : 294, "docs_moved" : NumberLong(109806635), "bytes_moved" : NumberLong("38294757573") }
    { "_id" : { "date" : "2024-09-22" }, "chunks_moved" : 737, "docs_moved" : NumberLong(266800041), "bytes_moved" : NumberLong("93047288531") }
    { "_id" : { "date" : "2024-09-21" }, "chunks_moved" : 1448, "docs_moved" : NumberLong(525308393), "bytes_moved" : NumberLong("183117965820") }
    { "_id" : { "date" : "2024-09-20" }, "chunks_moved" : 1459, "docs_moved" : NumberLong(530020503), "bytes_moved" : NumberLong("184390749022") }
    { "_id" : { "date" : "2024-09-19" }, "chunks_moved" : 1478, "docs_moved" : NumberLong(557833705), "bytes_moved" : NumberLong("186910196651") }
    { "_id" : { "date" : "2024-09-18" }, "chunks_moved" : 1360, "docs_moved" : NumberLong(508484825), "bytes_moved" : NumberLong("173486932689") }

    Cette sortie indique que le 2024-09-21, 183 117 965 820 octets (environ 170,5 Go) ont été migrés.

Étape 4 : Estimer la progression de la tâche et l'heure d'achèvement

Pour les versions MongoDB antérieures à 6,0

Remarque

Cette section s'applique aux versions suivantes :

  • Instances MongoDB de version antérieure à 6,0.

  • Instances MongoDB 6.0 dont la version mineure du moteur est antérieure à 7.0.1 (version de base 6.0.3). Pour vérifier votre version mineure du moteur, consultez le Guide des versions mineures MongoDB.

Après avoir obtenu le nombre de chunks migrés avec succès et la distribution actuelle des données, estimez la progression globale de la tâche et le délai d'achèvement prévu.

Supposons les conditions idéales suivantes lors de l'ajout d'un shard : le nombre total de chunks reste constant, le nombre de shards reste fixe (pas d'ajouts ou suppressions de shards concurrents), la charge de service reste stable et les paramètres du Balancer utilisent les valeurs par défaut. En utilisant l'exemple de l'Étape 3 sous Pour les versions MongoDB antérieures à 6,0, vous savez que :

  • Il y a 5 nœuds shard.

  • 300 chunks ont été migrés avec succès durant la fenêtre du Balancer.

  • La collection fragmentée <db>.<collection> compte 58 260 chunks au total (13 630 + 13 629 + 13 652 + 13 630 + 3 719 = 58 260).

Par conséquent, les calculs suivants peuvent être effectués :

  • À l'équilibre, chaque shard devrait contenir 11 652 chunks (58 260 ÷ 5 = 11 652).

  • Au rythme actuel de migration, l'achèvement de la tâche nécessite encore 26,4 jours ((11 652 – 3 719) ÷ 300 ≈ 26,4).

  • La tâche d'ajout de shard est achevée à 32 % (3 719 ÷ 11 652 = 32 %).

Remarque

Dans des scénarios réels, le nombre total de chunks augmente en raison des écritures continues et des divisions de chunks. Ce calcul suppose des conditions idéales ; le temps d'achèvement réel peut être plus long.

Pour les versions MongoDB 6.0 et ultérieures

Remarque

Cette section s'applique aux versions suivantes :

  • Instances MongoDB version 6.0 et ultérieures.

  • Instances MongoDB 6.0 dont la version mineure du moteur est 7.0.1 (version de base 6.0.3) ou ultérieure. Pour vérifier votre version mineure du moteur, consultez le Guide des versions mineures MongoDB.

Supposons que l'instance de cluster fragmenté ne possède qu'une seule collection nécessitant un équilibrage. En utilisant l'exemple de l'Étape 3 sous Pour les versions MongoDB 6.0 et ultérieures, vous savez que :

  • Il y a 4 nœuds shard.

  • Le 2024-09-21, environ 170,5 Go (183 117 965 820 octets) ont été migrés.

  • La collection fragmentée <db>.<collection> a un volume total de données d'environ 1 910,4 Go (2 051 303 530 231 octets).

Par conséquent, les calculs suivants peuvent être effectués :

  • À l'équilibre, chaque shard devrait contenir environ 477,6 Go (512 825 882 557,75 octets).

  • Le volume total de données devant être migré pour atteindre l'équilibre est de 875 559 682 949 octets (815,4 Go), réparti comme suit :

    Shard1 doit migrer 320 275 933 282,25 octets (833 101 815 840 – 512 825 882 557,75).

    Shard2 doit migrer 103 111 136 620,75 octets (409 714 745 937 – 512 825 882 557,75).

    Shard3 doit migrer 334 668 704 853,75 octets (178 157 177 704 – 512 825 882 557,75).

    Shard4 doit migrer 117 503 908 192,25 octets (630 329 790 750 – 512 825 882 557,75).

    (320 275 933 282,25 + 103 111 136 620,75 + 334 668 704 853,75 + 117 503 908 192,25 = 875 559 682 949)

  • Au rythme actuel de migration, l'équilibre sera atteint dans environ 4,8 jours (815,4 Go ÷ 170,5 Go/jour ≈ 4,8 jours).

Étape 5 : Vérifier si le flux de tâche est bloqué (suppression de shard)

Si la tâche de suppression de shard est bloquée, la sortie de sh.status() n'affiche aucune migration de chunk réussie au cours des périodes récentes, et le shard en cours de suppression contient encore des chunks qui n'ont pas migré. Dans ce cas, la tâche de suppression de shard ne peut pas s'achever, et les autres opérations d'exploitation et de maintenance sur l'instance dans la console ApsaraDB for MongoDB sont également affectées.

L'exemple suivant montre la sortie de sh.status() dans ce scénario.

autosplit:
  Currently enabled: yes
  balancer:
  Currently enabled:  yes
  Currently running:  no
    Balancer lock taken at Wed Sep 30 2020 02:03:11 GMT+0800 (CST) by ConfigServer:Balancer
  Failed balancer rounds in last 5 attempts:  0
  Migration Results for the last 24 hours:
    No recent migrations
  databases:
  {  "_id" : "report",  "primary" : "d-0xixxx",  "partitioned" : true }
    report.report
      shard key: { "GsId" : "hashed" }
      unique: false
      balancing: true
      chunks:
        d-0xixxx	9
        d-0xixxx	2133
        d-0xixxx	2152
        d-0xixxx	2116
        d-0xixxx	2133
      too many chunks to print, use verbose if you want to force print

Ce problème est probablement causé par des jumbo chunks qui bloquent le processus de suppression de shard. Exécutez la commande suivante pour vérifier la présence de jumbo chunks.

db.getSiblingDB("config").chunks.aggregate([{$match: {shard: "d-xxxxxxxxxxxxxx", jumbo:true}},{$group: {_id: "$ns", count: {$sum: 1}}}])

Les jumbo chunks sont généralement causés par une conception inappropriée de la clé de shard, telle que la présence de hot keys. Avant de poursuivre, classez les jumbo chunks dans l'une des catégories suivantes :

  • Divisible : La taille du chunk dépasse chunkSize, mais le chunk peut toujours être divisé en chunks plus petits en fonction de la clé de shard. Aucun traitement spécial n'est requis. Le Balancer migre le chunk après sa division.

  • Indivisible : La majorité des données du chunk partagent la même valeur de clé de shard (hot key). La taille des données dépasse chunkSize et le chunk ne peut pas être divisé. Utilisez l'une des méthodes suivantes pour gérer ce type de situation.

Essayez les méthodes suivantes en fonction de vos besoins métier :

  • Méthode 1 : Optimiser la conception de la clé de shard (solution racine aux problèmes de hot key)

    • Pour MongoDB 4.4 ou ultérieur, utilisez la commande refineCollectionShardKey pour ajouter des champs suffixes à la clé de shard existante. Cela augmente la cardinalité de la clé de shard et rend divisibles les jumbo chunks précédemment indivisibles.

    • Pour MongoDB 5.0 ou ultérieur, vous pouvez également utiliser la commande reshardCollection pour refragmenter la collection avec une nouvelle clé de shard. Pour plus d'informations, consultez la documentation Reshard a Collection.

  • Méthode 2 : Migrer le jumbo chunk (pour MongoDB 4.4 ou ultérieur, par exemple lorsqu'un jumbo chunk ne peut pas être migré lors de la suppression d'un shard)

    • Option 1 (recommandée) : Exécutez la commande clearJumboFlag pour effacer l'indicateur jumbo du chunk, puis définissez le paramètre du Balancer attemptToBalanceJumboChunks sur true afin de permettre au Balancer de migrer automatiquement le chunk. Cette méthode ne bloque pas les écritures pendant la copie des données. Les écritures ne sont bloquées que brièvement lors de la phase finale de la migration.

      Important
      • Si le volume d'écritures sur le chunk est élevé, la migration peut échouer en raison d'un débordement du cache incrémental. Après l'échec, le chunk est de nouveau marqué comme jumbo. Effacez à nouveau l'indicateur et réessayez.

      • Une fois la migration réussie, redéfinissez immédiatement attemptToBalanceJumboChunks sur false. Pour MongoDB 6.0 ou ultérieur, le Balancer effectue l'équilibrage en fonction des différences de volume de données entre les shards. Une fois le chunk surdimensionné migré vers n'importe quel shard, ce shard devient l'anomalie de volume de données. Si vous ne restaurez pas le paramètre, le Balancer migre le chunk d'avant en arrière entre les shards, entraînant un transfert continu de données et une surcharge de nettoyage des documents orphelins. Après restauration du paramètre, le chunk est de nouveau marqué comme jumbo lorsque la prochaine tentative de migration régulière échoue et n'est plus déplacé. Ce comportement est attendu et ne nécessite pas de nettoyer à nouveau l'indicateur.

    • Option 2 : Exécutez la commande moveChunk avec l'option forceJumbo: true. Cette méthode bloque toutes les écritures sur la collection du shard source pendant la copie des données, ce qui peut durer plusieurs heures pour les gros chunks. N'utilisez cette méthode que pendant les heures creuses ou lorsque les écritures peuvent être suspendues. Nous vous recommandons d'effectuer cette opération avec l'assistance du support technique Alibaba Cloud.

  • Méthode 3 : Supprimer des données. Si certaines données métier peuvent être supprimées, retirez les données du jumbo chunk pour réduire sa taille. Remarque : Une fois le chunk réduit, l'indicateur jumbo n'est pas automatiquement effacé. Vous devez toujours exécuter la commande clearJumboFlag (ou attendre que le chunk soit divisé avec succès) avant que le Balancer puisse le migrer.

  • Méthode 4 : Augmenter le paramètre chunkSize. Augmentez le paramètre chunkSize pour modifier le seuil des jumbo chunks. Cette méthode n'est efficace que lorsque la taille réelle du chunk dépasse légèrement le seuil actuel. Elle n'aide pas pour les chunks surdimensionnés causés par des hot keys. Nous vous recommandons d'effectuer cette opération avec l'assistance du support technique Alibaba Cloud.

Si aucune des méthodes précédentes ne résout le problème, soumettez un ticket pour contacter le support technique.

Accélérer les processus d'ajout ou de suppression

Pour achever plus rapidement l'ajout ou la suppression de shards, essayez ces méthodes d'accélération :

  • Augmentez la durée de la fenêtre du Balancer. Notez que la migration des chunks ajoute une charge supplémentaire susceptible d'affecter votre service. Évaluez les risques avant d'effectuer tout ajustement. Pour obtenir des instructions, consultez la rubrique Gérer le Balancer MongoDB.

  • Ajustez le paramètre setParameter.chunkMigrationConcurrency pour modifier la concurrence de migration des chunks. Pour plus de détails, consultez les Recommandations d'optimisation des paramètres.

  • Exécutez manuellement les opérations moveChunk pendant les heures creuses. Pour plus d'informations, consultez la documentation sh.moveChunk(). Exemple :

    sh.moveChunk("<db>.<collection>", {"<shard_key>": <value>}, "d-xxxxxxxxxxxxx")
    // example: 
    sh.moveChunk("records.people", { zipcode: "53187" }, "shard0019")
  • soumettez un ticket pour demander au support technique d'ajuster les paramètres du kernel.

Références