Tous les produits
Search
Centre de documentation

ApsaraDB for MongoDB:Troubleshoot unbalanced data after adding a new shard to a sharded cluster

Dernière mise à jour :Aug 08, 2026

L'ajout d'un nouveau shard est la méthode standard pour mettre à l'échelle horizontalement un cluster fragmenté MongoDB. Toutefois, la redistribution des données n'est pas toujours automatique : le nouveau shard peut rester inactif tandis que les anciens shards subissent une forte charge. Cette rubrique propose une démarche systématique pour diagnostiquer les causes du déséquilibre et y remédier.

Fonctionnement de l'équilibrage

L'équilibre des données entre les shards dépend entièrement du balancer intégré à MongoDB. Ce composant redistribue les données en migrant les chunks des shards surchargés vers ceux sous-utilisés. Si le balancer est arrêté, mal configuré ou bloqué par certaines propriétés de collection, les chunks restent à leur emplacement initial.

Le processus de diagnostic s'articule autour de deux axes :

  1. État du balancer — Vérifiez que le balancer est activé, actif et qu'il s'exécute dans une plage horaire valide.

  2. Possibilité de migration des données — Identifiez les propriétés de collection qui empêchent le balancer de déplacer les données, telles que les collections non fragmentées, des volumes de données inférieurs au seuil d'équilibrage ou la présence de jumbo chunks.

Diagnostic de l'état du balancer

Le balancer est le seul mécanisme permettant la migration des chunks. Commencez par vérifier son état avant d'explorer d'autres pistes.

Vérification de l'activation du balancer

Dans mongosh, exécutez :

sh.getBalancerState()

Si la sortie est false, le balancer est désactivé. Activez-le en suivant les instructions de la rubrique Gestion du balancer MongoDB.

Vérification de la fenêtre d'activité

Le balancer ne s'exécute que durant sa fenêtre d'activité configurée. Si l'heure actuelle se situe en dehors de cette plage, aucune migration n'a lieu.

Exécutez la commande suivante pour consulter la configuration de la fenêtre d'activité :

db.getSiblingDB("config").settings.find({_id:"balancer"})

Exemple de sortie :

{ _id: 'balancer', activeWindow: { start: '02:00', stop: '04:00' } }

Si la fenêtre est trop courte ou chevauche les heures de pointe, étendez-la afin de couvrir une période creuse plus longue. L'exemple suivant définit la fenêtre de 02:00 à 06:00 chaque jour :

db.getSiblingDB("config").settings.updateOne(
  { _id: "balancer" },
  { $set: { activeWindow: { start: "02:00", stop: "06:00" } } },
  { upsert: true }
)

Vérification de l'exécution en cours de l'équilibrage

Après l'ajout d'un shard, le balancer nécessite un certain temps pour migrer les données existantes. Un déséquilibre temporaire durant cette période est normal.

Exécutez la commande suivante pour déterminer si une tâche de migration est active :

sh.isBalancerRunning()

Si la sortie est true, l'équilibrage est en cours. Attendez qu'il se termine. Pour suivre la progression, consultez la rubrique Comment vérifier la progression de l'ajout ou de la suppression d'un nœud shard.

Analyse de la possibilité de migration des données

Si le balancer est activé et en cours d'exécution, mais que les données ne migrent pas, le problème provient probablement des propriétés de la collection. Les conditions suivantes peuvent bloquer la migration.

Vérification des collections non fragmentées volumineuses

Une base de données peut contenir à la fois des collections fragmentées et non fragmentées. Les collections non fragmentées stockent toutes leurs données sur le shard principal de la base de données ; le balancer ne peut pas migrer ces données. Si vos collections les plus volumineuses ne sont pas fragmentées, elles n'atteindront jamais le nouveau shard.

Exécutez le script suivant pour calculer l'espace de stockage occupé par les collections non fragmentées dans une base de données donnée :

// Replace "myDB" with the name of the database to check
var dbName = "myDB";

var unshardSize = 0;
var totalSize = 0;
var unshardedCollections = [];

db.getSiblingDB(dbName).getCollectionNames().forEach(function(collName) {
    var stats = db.getSiblingDB(dbName).getCollection(collName).stats();

    // Check the stats.sharded field and add up the storage size
    if (!stats.sharded) {
        unshardSize += (stats.storageSize || 0);
        unshardedCollections.push(dbName + "." + collName);
    }
    totalSize += (stats.storageSize || 0);

    // Sleep briefly after each query to avoid excessive load on the database
    sleep(200);
});

print("--- " + dbName + " ---");
print("Unsharded Collections Count: " + unshardedCollections.length);
print("--------------------");
print("Unsharded Storage Size (Bytes): " + unshardSize);
print("Total Storage Size (Bytes): " + totalSize);
print("--------------------");
print("Unsharded Collections List:");
printjson(unshardedCollections);
Ce script appelle stats() sur chaque collection, ce qui peut affecter les performances de la base de données. Le délai intégré sleep(200) permet de réduire ce risque. Pour les bases de données comportant de nombreuses collections, augmentez le délai à 2000 ou plus.

Si les collections non fragmentées représentent une part significative du stockage, activez la fragmentation pour celles-ci. Pour obtenir des conseils, consultez la rubrique Configuration de la fragmentation des données pour optimiser les performances des shards.

Vérification du seuil de migration pour les collections fragmentées (MongoDB 6.0+)

À partir de MongoDB 6.0.3, le balancer ne migre les chunks que lorsque la différence de volume de données entre les shards pour une collection donnée atteint un certain seuil. Par défaut, ce seuil correspond à trois fois la taille du chunk.

Avec une taille de chunk par défaut de 128 Mo, le déséquilibre des données entre deux shards doit atteindre au moins 384 Mo pour que le balancer déclenche la migration de cette collection. Les collections dont le volume total de données est inférieur à ce seuil sont considérées comme équilibrées et ne sont pas traitées.

Pour vérifier la distribution des données d'une collection entre les shards, exécutez :

db.<collection>.getShardDistribution()

Si la majorité des données d'une collection fragmentée est concentrée sur un seul shard et que le déséquilibre est inférieur à 384 Mo (avec la taille de chunk par défaut), le balancer n'intervient pas. Réduisez la valeur chunkSize de la collection pour abaisser le seuil et déclencher la migration :

// This example sets chunkSize to 16 MB for test_db.test_coll.
// Adjust chunkSize based on your collection's data volume and distribution.
db.adminCommand({
  configureCollectionBalancing: "test_db.test_coll",
  chunkSize: 16  // Unit: MB. Default for MongoDB 6.0+: 128 MB
})

Une fois la migration terminée, vérifiez que la distribution s'est améliorée :

db.<collection>.getShardDistribution()

Considérations relatives aux performances et à la configuration

Surcharge des performances liée à l'équilibrage

La migration des chunks (moveChunk) et la suppression de plage subséquente (RangeDeleter) consomment des ressources CPU et des opérations d'E/S disque sur les shards source et destination. Afin d'éviter tout impact sur le trafic en ligne, définissez la fenêtre d'activité du balancer pendant les heures creuses.

Risque lié à la configuration de chunkSize (versions MongoDB antérieures à 6.0)

Dans les versions de MongoDB antérieures à 6.0, une valeur chunkSize trop faible peut générer un nombre excessif de chunks. Cela augmente la charge liée aux métadonnées sur le serveur de configuration et entraîne une exécution trop fréquente du balancer. Définissez la valeur chunkSize en fonction du volume total de données et du taux de croissance prévu de la collection.

Étapes suivantes