Todos os produtos
Search
Central de documentação

ApsaraDB for MongoDB:Contagem de chunks desbalanceada entre shards após upgrade do MongoDB

Última atualização: Aug 24, 2026

Após atualizar uma instância de cluster sharded do ApsaraDB for MongoDB para o MongoDB 6,0 (versão secundária 7.0.1 ou posterior) ou para uma versão principal mais recente, a execução de sh.status() pode mostrar que as contagens de chunks estão visivelmente desiguais entre os shards, chegando a apresentar apenas um chunk por shard em alguns casos. Este tópico explica por que isso ocorre e como avaliar corretamente se os dados estão balanceados.

Sintoma

Alguns usuários relatam que, após atualizar uma instância de cluster sharded do ApsaraDB for MongoDB para o MongoDB 6,0 (versão secundária 7.0.1 ou posterior), o comando sh.status() indica que as contagens de chunks entre os shards não são mais aproximadamente iguais, diferentemente do comportamento anterior à atualização. As observações mais comuns incluem:

  • MongoDB 6,0 (versão secundária 7.0.1 e posteriores): As contagens de chunks variam significativamente entre os shards.

  • MongoDB 7.0 e posteriores: Cada shard pode conter apenas um chunk.

Você pode se perguntar:

  • Os dados não estão mais distribuídos uniformemente?

  • O balancer está com defeito?

  • A atualização apresentou algum erro?

Nota

Esse é o comportamento esperado após a atualização. Seus dados continuam distribuídos uniformemente e nenhuma ação é necessária. O novo balancer não utiliza mais a contagem de chunks como critério de balanceamento. Em vez disso, ele considera o tamanho real dos dados.

Por que isso acontece

Comportamento anterior ao MongoDB 6,0 versão secundária 7.0.1

Antes da versão secundária 7.0.1 do ApsaraDB for MongoDB 6,0, o cluster sharded balanceava os dados da seguinte forma:

  1. O tamanho padrão do chunk era de 64 MB.

  2. Quando um chunk ultrapassava 64 MB, ocorria uma divisão automática (AutoSplit) em chunks menores.

  3. O balancer inspecionava periodicamente a contagem de chunks em cada shard e migrava chunks (moveChunk) assim que a diferença excedia o limiar de migração.

  4. Com o tempo, cada shard passava a conter muitos chunks com contagens aproximadamente iguais.

Nesse modelo, o comando sh.status() exibia múltiplos chunks por shard, o que transmitia uma sensação intuitiva de que os dados estavam distribuídos de maneira uniforme.

Mudanças no MongoDB 6,0 a partir da versão secundária 7.0.1 (community 6.0.3)

A partir da **versão secundária 7.0.1 do ApsaraDB for MongoDB**, correspondente ao MongoDB community 6.0.3, o balancer passou a incorporar as seguintes mudanças:

  • Remoção do AutoSplit: Os chunks não são mais divididos automaticamente ao atingirem a capacidade máxima. A divisão ocorre apenas quando necessário, antes de uma migração.

  • Novo critério de balanceamento: Substituição da contagem de chunks pelo tamanho real dos dados.

  • Ajuste no limiar de migração: A migração é acionada quando o tamanho da mesma coleção difere em mais de três vezes o tamanho do chunk entre os shards. (O tamanho padrão do chunk no ApsaraDB for MongoDB 6,0 é de 128 MB, o que resulta em um limiar de 384 MB.)

  • Alteração na terminologia: O conceito de chunk perde ênfase em favor de "range". O comando moveChunk é substituído por moveRange.

  • Não é mais necessário executar sh.enableSharding() antes de aplicar sharding a uma coleção.

Efeito: Como o AutoSplit foi removido e a contagem de chunks deixou de ser o critério de balanceamento, as quantidades de chunks entre os shards podem ficar desiguais, o que é normal. Para mais informações, consulte sh.enableAutoSplit().

Novidade no MongoDB 7.0: AutoMerger

O MongoDB 7.0 introduz o recurso AutoMerger:

  • O balancer mescla automaticamente chunks contíguos e mescláveis no mesmo shard.

  • O AutoMerger executa em segundo plano como parte das operações de balanceamento e vem ativado por padrão.

  • A execução ocorre a cada autoMergerIntervalSecs segundos.

  • Caso haja uma janela de balanceamento configurada, o AutoMerger opera exclusivamente dentro desse período.

Efeito: No MongoDB 7.0 e versões posteriores, o AutoMerger pode eventualmente consolidar os chunks de cada shard em um único chunk. Esse comportamento também é normal. Para mais detalhes, visualize AutoMerger.

Motivos dessas alterações

O balancer baseado em contagem de chunks nas versões anteriores apresentava várias desvantagens:

Problema

Descrição

Jumbo chunks

Quando a chave de shard tem baixa cardinalidade, todos os documentos de um chunk compartilham o mesmo valor de chave, impedindo a divisão do chunk. Os shards podem terminar com a mesma contagem de chunks, mas com uso de disco muito diferente.

Write skew

Se a chave de shard do tipo range contiver um componente monotonicamente crescente, novas escritas concentram-se em um único shard.

Consumo de recursos

Operações frequentes de AutoSplit e moveChunk consomem recursos significativos de CPU e afetam o desempenho da carga de trabalho.

Adotar o tamanho real dos dados como critério de balanceamento oferece uma visão mais precisa da distribuição de dados e reduz divisões e migrações desnecessárias de chunks.

Mapeamento de versões

Versão do ApsaraDB for MongoDB

Versão Community

Comportamento do balancer

MongoDB 4.4

MongoDB 4.4

Legado: AutoSplit + balanceamento por contagem de chunks

MongoDB 5.0

MongoDB 5.0

Legado: AutoSplit + balanceamento por contagem de chunks

MongoDB 6,0 (versão secundária 7.0.0)

MongoDB 6.0.0

Legado: AutoSplit + balanceamento por contagem de chunks

MongoDB 6,0 (versão secundária 7.0.1 e posteriores)

MongoDB 6.0.3

AutoSplit removido + balanceamento por tamanho (contagens de chunks podem ficar desiguais)

MongoDB 7.0 e posteriores

MongoDB 7.0+

AutoSplit removido + balanceamento por tamanho + AutoMerger consolida chunks

Comparação entre versões

Item

MongoDB 6,0 (antes da versão secundária 7.0.1)

MongoDB 6,0 (versão secundária 7.0.1 e posteriores)

MongoDB 7.0 e posteriores

AutoSplit

Ativado. Chunks divididos automaticamente ao atingirem a capacidade.

Desativado

Desativado

AutoMerger

Não disponível

Não disponível

Ativado. Chunks são mesclados automaticamente.

Critério de balanceamento

Contagem de chunks

Tamanho real dos dados

Tamanho real dos dados

Contagem de chunks por shard

Múltiplos, aproximadamente iguais

Desigual, pode variar entre shards

Pode convergir para um

Limiar de migração

Diferença na contagem de chunks ≥ 1 (MongoDB 4.2 e posteriores)

Tamanho dos dados difere em mais de três vezes o tamanho do chunk

Tamanho dos dados difere em mais de três vezes o tamanho do chunk

enableSharding

Obrigatório antes do sharding

Opcional no MongoDB 6,0 e posteriores

Opcional

Como avaliar o balanceamento

Contagens de chunks via sh.status()

Tamanhos de dados via getShardDistribution()

Tamanhos de dados via getShardDistribution()

Dados de teste

Os resultados a seguir foram obtidos após a ferramenta YCSB inserir 50 milhões de registros em instâncias de cluster sharded do ApsaraDB for MongoDB executando MongoDB 4.4, MongoDB 6,0 e MongoDB 8.0.

MongoDB 4.4 (comportamento legado)

Execute sh.status(). Observe o campo chunkMetadata na saída. Cada shard possui 435 chunks, com contagens idênticas. Esse é o resultado do mecanismo legado de AutoSplit:

mongos> sh.status()
shardingVersion
{ _id: 1, clusterId: ObjectId('69fbfda6dec76b373f5eda81') }
---
shards
[
  {
    _id: 'd-uf6xxxx1',
    host: 'mgset-1xxxxx0/192.168.XX.2:3005.192.168.XX.11:3002',
    state: 1
  },
  {
    _id: 'd-uf6xxxx2',
    host: 'mgset-1xxxxx1/192.168.XX.4:3002.192.168.XX.5:3002',
    state: 1
  }
]
---
active mongoses
[ { '4.4.30': 2 } ]
---
autosplit
{ 'Currently enabled': 'yes' }
---
balancer
{
  'Currently enabled': 'yes',
  'Failed balancer rounds in last 5 attempts': 0,
  'Currently running': 'no',
  'Migration Results for the last 24 hours': { '947': 'Success' }
}
---
databases
[
  {
    database: {
      _id: 'ycsb',
      primary: 'd-uf6xxxx2',
      partitioned: true
    },
    collections: {
      'ycsb.test1': {
        shardKey: { _id: 'hashed' },
        unique: false,
        balancing: true,
        chunkMetadata: [
          { shard: 'd-uf6xxxx1', nChunks: 435 },
          { shard: 'd-uf6xxxx2', nChunks: 435 }
        ],
        chunks: [
          'too many chunks to print, use verbose if you want to force print'
        ],
        tags: []
      }
    }
  }
]

Execute db.test1.getShardDistribution(). Analise os campos data (tamanho dos dados) e chunks (contagem de chunks) de cada shard:

mongos> use ycsb
switched to db ycsb
mongos> db.test1.getShardDistribution()
Shard d-uf6xxxx1 at mgset-1xxxxx0/192.168.XX.2:3005,192.168.XX.11:3002
{
  data: '27.2GiB',
  docs: 25014674,
  chunks: 435,
  'estimated data per chunk': '64.04MiB',
  'estimated docs per chunk': 57504
}
---
Shard d-uf6xxxx2 at mgset-1xxxxx1/192.168.XX.4:3002,192.168.XX.5:3002
{
  data: '36.23GiB',
  docs: 33313293,
  chunks: 435,
  'estimated data per chunk': '85.29MiB',
  'estimated docs per chunk': 76582
}
---
Totals
{
  data: '63.44GiB',
  docs: 58327967,
  chunks: 870,
  'Shard d-uf6xxxx1': [
    '42.88 % data',
    '42.88 % docs in cluster',
    '1KiB avg obj size on shard'
  ],
  'Shard d-uf6xxxx2': [
    '57.11 % data',
    '57.11 % docs in cluster',
    '1KiB avg obj size on shard'
  ]
}

MongoDB 6,0 (versão secundária 7.0.1 e posteriores)

Execute sh.status(). Verifique o campo chunkMetadata. As contagens de chunks apresentam-se visivelmente desiguais entre os shards (216 contra 1):

mongos> sh.status()
shardingVersion
{ _id: 1, clusterId: ObjectId('69fbfdc420578638757c1d06') }
---
shards
[
  {
    _id: 'd-uf6xxxx3',
    host: 'mgset-1xxxxx2/192.168.XX.7:3002.192.168.XX.8:3002',
    state: 1,
    topologyTime: Timestamp({ t: 1778122310, i: 2 })
  },
  {
    _id: 'd-uf6xxxx4',
    host: 'mgset-1xxxxx3/192.168.XX.9:3002.192.168.XX.10:3002',
    state: 1,
    topologyTime: Timestamp({ t: 1778122310, i: 9 })
  }
]
---
active mongoses
[ { '6.0.27': 2 } ]
---
autosplit
{ 'Currently enabled': 'yes' }
---
balancer
{
  'Currently running': 'no',
  'Currently enabled': 'yes',
  'Failed balancer rounds in last 5 attempts': 0,
  'Migration Results for the last 24 hours': { '216': 'Success' }
}
---
databases
[
  {
    database: {
      _id: 'ycsb',
      primary: 'd-uf6xxxx4',
      partitioned: false,
      version: {
        uuid: UUID('4ee45231-9585-4dba-8f34-f624860e1a79'),
        timestamp: Timestamp({ t: 1778122930, i: 1 }),
        lastMod: 1
      }
    },
    collections: {
      'ycsb.test2': {
        shardKey: { _id: 'hashed' },
        unique: false,
        balancing: true,
        allowMigrations: true,
        chunkMetadata: [
          { shard: 'd-uf6xxxx3', nChunks: 216 },
          { shard: 'd-uf6xxxx4', nChunks: 1 }
        ],
        chunks: [
          'too many chunks to print, use verbose if you want to force print'
        ],
        tags: []
      }
    }
  }
]

Execute db.test2.getShardDistribution(). Observe a porcentagem de data em cada shard. Apesar da grande diferença nas contagens de chunks (216 contra 1), os dados continuam distribuídos uniformemente (50,31% contra 49,68%):

mongos> use ycsb
switched to db ycsb
mongos> db.test2.getShardDistribution()
Shard d-uf6xxxx4 at mgset-1xxxxx3/192.168.XX.9:3002,192.168.XX.10:3002
{
  data: '27.36GiB',
  docs: 32285618,
  chunks: 1,
  'estimated data per chunk': '27.36GiB',
  'estimated docs per chunk': 32285618
}
---
Shard d-uf6xxxx3 at mgset-1xxxxx2/192.168.XX.7:3002,192.168.XX.8:3002
{
  data: '27.01GiB',
  docs: 24841944,
  chunks: 216,
  'estimated data per chunk': '128.09MiB',
  'estimated docs per chunk': 115009
}
---
Totals
{
  data: '54.38GiB',
  docs: 57127562,
  chunks: 217,
  'Shard d-uf6xxxx4': [
    '50.31 % data',
    '56.51 % docs in cluster',
    '1KiB avg obj size on shard'
  ],
  'Shard d-uf6xxxx3': [
    '49.68 % data',
    '43.48 % docs in cluster',
    '1KiB avg obj size on shard'
  ]
}

MongoDB 8.0 (com AutoMerger)

Logo após a conclusão da migração, execute sh.status(). Verifique o campo chunkMetadata. Cada shard ainda apresenta múltiplos chunks (55 contra 1):

mongos> sh.status()
shardingVersion
{ _id: 1, clusterId: ObjectId('69fbfdbdd7b0e3d9551dd833') }
---
shards
[
  {
    _id: 'd-uf6xxxx5',
    host: 'mgset-1xxxxx4/192.168.XX.1:3000.192.168.XX.3:3002',
    state: 1,
    topologyTime: Timestamp({ t: 1778122320, i: 8 }),
    replSetConfigVersion: Long('-1')
  },
  {
    _id: 'd-uf6xxxx6',
    host: 'mgset-1xxxxx5/192.168.XX.5:3003.192.168.XX.6:3003',
    state: 1,
    topologyTime: Timestamp({ t: 1778122319, i: 10 }),
    replSetConfigVersion: Long('-1')
  }
]
---
active mongoses
[ { '8.0.18': 2 } ]
---
autosplit
{ 'Currently enabled': 'yes' }
---
balancer
{
  'Currently enabled': 'yes',
  'Failed balancer rounds in last 5 attempts': 0,
  'Currently running': 'no',
  'Migration Results for the last 24 hours': { '216': 'Success' }
}
---
databases
[
  {
    database: {
      _id: 'ycsb',
      primary: 'd-uf6xxxx6',
      version: {
        uuid: UUID('98799357-048e-45bc-a472-387165e0fe74'),
        timestamp: Timestamp({ t: 1778122931, i: 2 }),
        lastMod: 1
      }
    },
    collections: {
      'ycsb.test2': {
        shardKey: { _id: 'hashed' },
        unique: false,
        balancing: true,
        allowMigrations: true,
        chunkMetadata: [
          { shard: 'd-uf6xxxx5', nChunks: 55 },
          { shard: 'd-uf6xxxx6', nChunks: 1 }
        ],
        chunks: [
          'too many chunks to print, use verbose if you want to force print'
        ],
        tags: []
      }
    }
  }
]

Após a conclusão do AutoMerger, execute sh.status() novamente. Observe o campo chunkMetadata. Agora, cada shard possui apenas um chunk:

mongos> sh.status()
shardingVersion
{ _id: 1, clusterId: ObjectId('69fbfdbdd7b0e3d9551dd833') }
---
shards
[
  {
    _id: 'd-uf6xxxx5',
    host: 'mgset-1xxxxx4/192.168.XX.1:3000.192.168.XX.3:3002',
    state: 1,
    topologyTime: Timestamp({ t: 1778122320, i: 8 }),
    replSetConfigVersion: Long('-1')
  },
  {
    _id: 'd-uf6xxxx6',
    host: 'mgset-1xxxxx5/192.168.XX.5:3003.192.168.XX.6:3003',
    state: 1,
    topologyTime: Timestamp({ t: 1778122319, i: 10 }),
    replSetConfigVersion: Long('-1')
  }
]
---
active mongoses
[ { '8.0.18': 2 } ]
---
autosplit
{ 'Currently enabled': 'yes' }
---
balancer
{
  'Currently enabled': 'yes',
  'Failed balancer rounds in last 5 attempts': 0,
  'Currently running': 'no',
  'Migration Results for the last 24 hours': { '216': 'Success' }
}
---
databases
[
  {
    database: {
      _id: 'ycsb',
      primary: 'd-uf6xxxx6',
      version: {
        uuid: UUID('98799357-048e-45bc-a472-387165e0fe74'),
        timestamp: Timestamp({ t: 1778122931, i: 2 }),
        lastMod: 1
      }
    },
    collections: {
      'ycsb.test2': {
        shardKey: { _id: 'hashed' },
        unique: false,
        balancing: true,
        allowMigrations: true,
        chunkMetadata: [
          { shard: 'd-uf6xxxx5', nChunks: 1 },
          { shard: 'd-uf6xxxx6', nChunks: 1 }
        ],
        chunks: [
          { min: { _id: MinKey() }, max: { _id: Long('-58615400192952365') }, 'on shard': 'd-uf6xxxx5', 'last modified': Timestamp({ t: 217, i: 2 }) },
          { min: { _id: Long('-58615400192952365') }, max: { _id: MaxKey() }, 'on shard': 'd-uf6xxxx6', 'last modified': Timestamp({ t: 217, i: 1 }) }
        ],
        tags: []
      }
    }
  }
]

Execute db.test2.getShardDistribution(). Analise a porcentagem de data. Mesmo com cada shard contendo apenas um chunk, os dados permanecem distribuídos uniformemente (49,67% contra 50,32%):

mongos> use ycsb
switched to db ycsb
mongos> db.test2.getShardDistribution()
Shard d-uf6xxxx5 at mgset-1xxxxx4/192.168.XX.1:3000,192.168.XX.3:3002
{
  data: '27.01GiB',
  docs: 24841944,
  chunks: 1,
  'estimated data per chunk': '27.01GiB',
  'estimated docs per chunk': 24841944
}
---
Shard d-uf6xxxx6 at mgset-1xxxxx5/192.168.XX.5:3003,192.168.XX.6:3003
{
  data: '27.37GiB',
  docs: 35898246,
  chunks: 1,
  'estimated data per chunk': '27.37GiB',
  'estimated docs per chunk': 35898246
}
---
Totals
{
  data: '54.39GiB',
  docs: 60740190,
  chunks: 2,
  'Shard d-uf6xxxx5': [
    '49.67 % data',
    '40.89 % docs in cluster',
    '1KiB avg obj size on shard'
  ],
  'Shard d-uf6xxxx6': [
    '50.32 % data',
    '59.1 % docs in cluster',
    '1KiB avg obj size on shard'
  ]
}

Conclusão: Os dados de teste nas três versões demonstram que, independentemente das variações na contagem de chunks (870 → 217 → 2), os dados permanecem distribuídos uniformemente entre os shards. A diferença nas contagens de chunks deve-se exclusivamente a mudanças na gestão interna e não afeta a distribuição real dos dados nem sua carga de trabalho.

Como avaliar corretamente o balanceamento de dados

Após atualizar para o MongoDB 6,0 (versão secundária 7.0.1) ou posterior, utilize os métodos abaixo para avaliar o balanceamento:

Recomendado: getShardDistribution()

Conecte-se ao mongos e execute:

use <your_database>
db.<your_collection>.getShardDistribution()

Esse comando exibe o tamanho dos dados, a contagem de documentos e a porcentagem da coleção em cada shard, oferecendo uma visão precisa da distribuição.

Auxiliar: db.stats()

use <your_database>
db.stats()

Retorna o uso geral de armazenamento do banco de dados entre os shards.

Não recomendado: contagens de chunks via sh.status()

O comando sh.status() continua funcional, porém as contagens de chunks não refletem mais o balanceamento dos dados. Contagens desiguais ou um único chunk por shard são comportamentos normais e não indicam problemas na distribuição de dados.

Perguntas frequentes

P: Perderei dados se as contagens de chunks ficarem desiguais ou caírem para um após a atualização?

R: Não. Chunks são apenas uma unidade lógica interna usada pelo MongoDB para gerenciar dados. Alterações nas contagens de chunks não afetam os dados reais, que permanecem intactos em cada shard.

P: Preciso executar comandos de divisão manualmente para dividir chunks?

R: Não. O novo balancer divide os dados conforme necessário antes das migrações. Nenhuma intervenção manual é necessária.

P: O balancer continua funcionando após a atualização?

R: Sim. O balancer continua operando, mas utiliza o tamanho dos dados em vez da contagem de chunks como critério. Quando a diferença no tamanho dos dados entre os shards excede o limiar, o balancer migra os dados automaticamente.

P: Qual a diferença no comportamento de chunks entre o MongoDB 6,0 e o MongoDB 7.0 após a atualização?

R: O MongoDB 6,0 (versão secundária 7.0.1 e posteriores) remove o AutoSplit e adota o balanceamento por tamanho, de modo que as contagens de chunks entre shards podem ficar desiguais. O MongoDB 7.0 adiciona o AutoMerger, que consolida os chunks. Eventualmente, cada shard pode passar a ter um único chunk. Em ambos os casos, os dados permanecem distribuídos uniformemente.

P: É normal haver múltiplos chunks durante a migração?

R: Sim. O balancer realiza divisões necessárias durante a migração, portanto múltiplos chunks podem aparecer temporariamente. No MongoDB 7.0 e posteriores, o AutoMerger os consolida após o término da migração. No MongoDB 6,0, os chunks podem persistir, mas o balanceamento dos dados não é afetado.

P: Essa mudança afeta minha carga de trabalho?

R: Não. A alteração é transparente para as aplicações. Na prática, o novo comportamento reduz divisões e migrações desnecessárias, o que frequentemente melhora o desempenho.

Referências