Todos os produtos
Search
Central de documentação

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

Última atualização: Jun 26, 2026

Adicionar um novo shard é a forma padrão de escalar horizontalmente um cluster MongoDB com sharding. No entanto, os dados nem sempre se redistribuem automaticamente — o novo shard pode ficar ocioso enquanto os antigos permanecem sobrecarregados. Este tópico apresenta um processo sistemático para diagnosticar a falta de balanceamento e resolver o desequilíbrio.

Como funciona o balanceamento

O equilíbrio de dados entre shards depende inteiramente do balancer nativo do MongoDB. Esse componente redistribui os dados migrando chunks de shards sobrecarregados para aqueles com menor carga. Se o balancer não estiver em execução, estiver mal configurado ou propriedades da coleção o bloquearem, os chunks permanecerão em seus locais originais.

O diagnóstico envolve duas etapas:

  1. Estado do balancer — Confirme se o balancer está ativado, ativo e executando dentro de uma janela válida.

  2. Migração de dados — Identifique propriedades da coleção que impedem o balancer de mover dados, como coleções sem sharding, volumes abaixo do limiar de balanceamento ou presença de jumbo chunks.

Diagnosticar o estado do balancer

O balancer é o único mecanismo responsável pela migração de chunks. Comece por aqui antes de investigar outros aspectos.

Verificar se o balancer está ativado

No mongosh, execute:

sh.getBalancerState()

Se a saída for false, o balancer está desativado. Ative-o seguindo as instruções em Gerencie o balancer do MongoDB.

Verificar a janela ativa

O balancer executa apenas durante sua janela ativa configurada. Fora desse período, nenhuma migração ocorre.

Para verificar a configuração da janela ativa, execute o comando:

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

Exemplo de saída:

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

Caso a janela seja muito curta ou coincida com horários de pico de tráfego, estenda-a para cobrir um período maior fora do pico. O exemplo a seguir define a janela diária das 02:00 às 06:00:

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

Verificar se o balanceamento já está em andamento

Após adicionar um shard, o balancer precisa de tempo para migrar os dados existentes. É esperado haver desequilíbrio durante esse período.

Para verificar se há uma tarefa de migração ativa, execute:

sh.isBalancerRunning()

Se a saída for true, o balanceamento está em andamento. Aguarde a conclusão. Para acompanhar o progresso, consulte Como verificar o progresso da adição ou remoção de um nó shard.

Analisar a possibilidade de migração de dados

Se o balancer estiver ativado e em execução, mas os dados não se moverem, o problema provavelmente reside nas propriedades da coleção. As condições a seguir podem bloquear a migração.

Verificar grandes coleções sem sharding

Um banco de dados pode conter coleções com e sem sharding. Coleções sem sharding armazenam todos os dados no shard primário do banco — o balancer não consegue migrá-los. Se suas maiores coleções não tiverem sharding, elas nunca alcançarão o novo shard.

Execute o script a seguir para calcular o armazenamento ocupado por coleções sem sharding em um determinado banco de dados:

// 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);
Este script chama stats() em cada coleção, o que pode afetar o desempenho do banco de dados. O atraso integrado sleep(200) reduz esse risco. Para bancos de dados com muitas coleções, aumente o atraso para 2000 ou mais.

Se as coleções sem sharding representarem uma parcela significativa do armazenamento, ative o sharding nelas. Para obter orientações, consulte Configurar sharding de dados para aproveitar totalmente o desempenho dos shards.

Verificar se coleções com sharding estão abaixo do limiar de migração (MongoDB 6.0+)

A partir do MongoDB 6.0.3, o balancer só migra chunks quando a diferença de volume de dados entre shards para uma determinada coleção atinge um limiar. O valor padrão corresponde a três vezes o tamanho do chunk.

Com o tamanho padrão de chunk de 128 MB, o desequilíbrio de dados entre dois shards deve atingir pelo menos 384 MB antes que o balancer acione a migração para essa coleção. Coleções com volume total inferior a esse limiar são consideradas equilibradas e não sofrem alterações.

Para verificar a distribuição dos dados de uma coleção entre os shards, execute:

db.<collection>.getShardDistribution()

Se a maior parte dos dados de uma coleção com sharding estiver concentrada em um único shard e o desequilíbrio for inferior a 384 MB (considerando o tamanho padrão de chunk), o balancer não agirá. Reduza o chunkSize da coleção para diminuir o limiar e acionar a migração:

// 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
})

Após a conclusão da migração, verifique se a distribuição melhorou:

db.<collection>.getShardDistribution()

Considerações sobre desempenho e configuração

Sobrecarga de desempenho do balanceamento

A migração de chunks (moveChunk) e a subsequente exclusão de intervalos (RangeDeleter) consomem CPU e E/S de disco tanto nos shards de source quanto nos de destino. Para evitar impactos no tráfego online, defina a janela ativa do balancer para horários fora do pico.

Risco de configuração de chunkSize (versões do MongoDB anteriores à 6.0)

Em versões do MongoDB anteriores à 6.0, definir o chunkSize com um valor muito pequeno pode criar um número excessivo de chunks. Isso aumenta a sobrecarga de metadados no config server e faz com que o balancer execute com muita frequência. Defina o chunkSize com base no volume total de dados e na taxa de crescimento esperada da coleção.

Próximos passos