Este tópico descreve como monitorar o progresso de tarefas de adição ou remoção de nós de shard e como identificar condições anormais que possam bloqueá-las.
Contexto
Após adicionar ou remover nós de shard de uma instância de cluster com sharding, a tarefa pode permanecer incompleta por um longo período. As seções a seguir explicam como solucionar esse problema.
Antes de começar, compreenda os seguintes conceitos:
Entenda os modos de implantação de instâncias de conjunto de réplicas e de cluster com sharding do MongoDB, bem como as diferenças entre essas arquiteturas. Para mais informações, consulte Arquitetura de conjunto de réplicas e Arquitetura de cluster com sharding.
Compreenda o funcionamento do Balancer do MongoDB. Para mais informações, consulte gerencie o Balancer do MongoDB.
Saiba como o MongoDB divide os dados. O MongoDB particiona os dados em chunks.
Conheça os comandos comuns de O&M para instâncias de cluster com sharding do MongoDB, como
sh.status().Aprenda a usar o mongo shell, o mongosh ou outras ferramentas de visualização.
Verificar o progresso da tarefa
Etapa 1: Verifique se o Balancer está ativado
A migração de chunks durante a adição ou remoção de shards depende do Balancer. Se o Balancer estiver desativado, ocorrerão os seguintes problemas:
Ao adicionar um nó de shard: os dados dos chunks não migram para o novo nó, que fica incapaz de processar o tráfego do serviço.
Ao remover um nó de shard: os chunks do shard de destino não migram, bloqueando a tarefa de remoção.
Ative o Balancer para garantir a migração normal dos chunks. Para obter instruções, consulte gerencie o Balancer do MongoDB.
Use um dos seguintes métodos para verificar se o Balancer está ativado:
-
Método 1: execute o comando
sh.status().Se o Balancer estiver ativado, a saída será semelhante ao exemplo a seguir.
... 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 ...Se a saída exibir
“Currently enabled: no”, o Balancer estará desativado. -
Método 2: execute o comando
sh.getBalancerState().Se o comando retornar
true, o Balancer estará ativado.Se o comando retornar
false, o Balancer estará desativado.
Etapa 2: Verifique se a janela do Balancer é muito curta
O Balancer controla a velocidade de migração e executa o processo apenas durante sua janela ativa. Caso a migração não termine na janela atual, ela será retomada na próxima até a conclusão. Uma janela curta pode retardar as tarefas de adição ou remoção de shards. Para ajustar a janela do Balancer, consulte gerencie o Balancer do MongoDB.
Use um dos seguintes métodos para verificar a janela do Balancer:
-
Método 1: execute o comando
sh.status().O exemplo a seguir exibe uma janela do Balancer das 08:30 às 11:30 no horário local do servidor (total de 3 horas).
... 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étodo 2: execute o comando
sh.getBalancerWindow().O exemplo a seguir mostra claramente o horário da janela, sendo especialmente útil quando há muitas coleções com sharding.
{ "start" : "08:30", "stop" : "11:30" }
Etapa 3: Colete as informações necessárias para estimar o progresso da tarefa
Para versões do MongoDB anteriores à 6.0
Esta seção se aplica às seguintes versões:
Instâncias do MongoDB anteriores à versão 6.0.
Instâncias do MongoDB 6.0 com uma versão secundária do mecanismo anterior à 7.0.1 (versão de base 6.0.3). Para verificar a versão secundária do seu mecanismo, consulte Guia de versões secundárias do MongoDB.
Antes de estimar o progresso da tarefa, obtenha as estatísticas de execução do Balancer (contagens de sucessos e falhas) e as informações de chunks para as coleções com sharding que aguardam migração.
Para obter os resultados de execução do Balancer e as informações sobre chunks de coleções com sharding pendentes de migração, use um dos dois métodos a seguir:
-
Método 1: Use a saída do comando
sh.status().Foque em duas partes da saída do
sh.status(). A primeira parte exibe os resultados recentes do Balancer, como neste exemplo.... 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: ...A segunda parte apresenta os detalhes dos chunks das coleções com sharding, como neste exemplo.
... 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 ...Neste exemplo, "d-xxxxxxxxxxxxxxx5" é o nó de shard recém-adicionado. Além disso, execute o comando
getShardDistributionno banco de dados que contém a coleção com sharding para obter detalhes da distribuição de chunks, conforme mostrado abaixo.use <db> db.<collection>.getShardDistribution() -
Método 2: Leia os dados relevantes diretamente do banco de dados config.
A seguir, visualize as estatísticas de chunks agregadas por shard da seguinte forma.
db.getSiblingDB("config").chunks.aggregate([{$group: {_id: "$shard", count: {$sum: 1}}}])Para que você visualize os chunks em um shard específico agrupados por namespace, execute o comando a seguir.
db.getSiblingDB("config").chunks.aggregate([{$match: {shard: "d-xxxxxxxxxxxxxx"}},{$group: {_id: "$ns", count: {$sum: 1}}}])Para contar os chunks migrados com sucesso para um nó de shard específico nas últimas 24 horas, execute o comando a seguir.
// 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()
Para versões do MongoDB 6.0 e posteriores
Esta seção se aplica às seguintes versões:
Instâncias do MongoDB da versão 6.0 e posteriores.
Instâncias do MongoDB 6.0 com uma versão secundária do mecanismo 7.0.1 (versão de base 6.0.3) ou posterior. Para verificar a versão secundária do seu mecanismo, consulte Guia de versões secundárias do MongoDB.
Antes de estimar o progresso da tarefa, concentre-se na distribuição de dados entre os shards. Ainda é possível usar a saída do sh.status() como referência, mas mude o foco da contagem desigual de chunks para a distribuição real do volume de dados.
-
Obtenha informações sobre a distribuição de coleções com sharding e o equilíbrio de dados.
Use o comando
getShardDistributionpara obter detalhes da distribuição e concentre-se no equilíbrio dos dados. Exemplo: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 : 48BPara isso, execute o comando a seguir para obter informações de distribuição mais detalhadas (incluindo contagem de documentos, tamanho total, contagem de documentos órfãos e tamanho dos órfãos):
db.getSiblingDB("admin").aggregate( [{ $shardedDataDistribution: { } },{ $match: { "ns": "<db>.<collection>" } }] ).pretty()A saída do exemplo a seguir exibe um desequilíbrio notável de dados entre os 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 } ] }A partir dessa saída, é possível determinar que a instância possui 4 nós de shard e que o volume total de dados da coleção com sharding
<db>.<collection>é de aproximadamente 2051303530231 bytes (833101815840 + 409714745937 + 178157177704 + 630329790750 = 2051303530231), ou cerca de 1910,4 GB. -
Agora, visualize o volume de dados migrados com sucesso no último dia.
Para isso, execute a consulta a seguir:
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)Exemplo de saída:
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") }Essa saída indica que, em
2024-09-21, 183117965820 bytes (cerca de 170,5 GB) foram migrados.
Etapa 4: Estime o progresso da tarefa e o tempo de conclusão
Para versões do MongoDB anteriores à 6.0
Esta seção se aplica às seguintes versões:
Instâncias do MongoDB anteriores à versão 6.0.
Instâncias do MongoDB 6.0 com uma versão secundária do mecanismo anterior à 7.0.1 (versão de base 6.0.3). Para verificar a versão secundária do seu mecanismo, consulte Guia de versões secundárias do MongoDB.
Após obter o número de chunks migrados com sucesso e a distribuição atual dos dados, estime o progresso geral da tarefa e o tempo esperado de conclusão.
Considere as seguintes condições ideais durante a adição de shards: a contagem total de chunks permanece constante, a quantidade de shards se mantém fixa (sem adições ou remoções simultâneas), a carga do serviço permanece estável e os parâmetros do Balancer usam valores padrão. Com base no exemplo da Etapa 3 em Para versões do MongoDB anteriores à 6.0, tem-se o seguinte:
Há 5 nós de shard.
300 chunks foram migrados com sucesso durante a janela do Balancer.
A coleção com sharding
<db>.<collection>tem um total de 58260 chunks (13630 + 13629 + 13652 + 13630 + 3719 = 58260).
Portanto, é possível calcular o seguinte:
Em equilíbrio, cada shard deve conter 11652 chunks (58260 ÷ 5 = 11652).
Na taxa de migração atual, a conclusão da tarefa requer mais 26,4 dias ((11652 – 3719) ÷ 300 ≈ 26,4).
A tarefa de adição de shard está 32% concluída (3719 ÷ 11652 = 32%).
Em cenários reais, a quantidade total de chunks aumenta devido a gravações contínuas e divisões de chunks. Este cálculo considera condições ideais; o tempo real de conclusão pode ser maior.
Para versões do MongoDB 6.0 e posteriores
Esta seção se aplica às seguintes versões:
Instâncias do MongoDB da versão 6.0 e posteriores.
Instâncias do MongoDB 6.0 com uma versão secundária do mecanismo 7.0.1 (versão de base 6.0.3) ou posterior. Para verificar a versão secundária do seu mecanismo, consulte Guia de versões secundárias do MongoDB.
Considere que a instância de cluster com sharding tenha apenas uma coleção que requer balanceamento. Com base no exemplo da Etapa 3 em Para versões do MongoDB 6.0 e posteriores, tem-se o seguinte:
Há 4 nós de shard.
Em
2024-09-21, aproximadamente 170,5 GB (183117965820 bytes) foram migrados.A coleção com sharding
<db>.<collection>tem um volume total de dados de cerca de 1910,4 GB (2051303530231 bytes).
Portanto, é possível calcular o seguinte:
Em equilíbrio, cada shard deve conter aproximadamente 477,6 GB (512825882557,75 bytes).
-
O volume total de dados que precisa ser migrado para alcançar o equilíbrio é de 875559682949 bytes (815,4 GB), detalhado da seguinte forma:
O Shard1 precisa migrar 320275933282,25 bytes (833101815840 – 512825882557,75).
O Shard2 precisa migrar 103111136620,75 bytes (409714745937 – 512825882557,75).
O Shard3 precisa migrar 334668704853,75 bytes (178157177704 – 512825882557,75).
O Shard4 precisa migrar 117503908192,25 bytes (630329790750 – 512825882557,75).
(320275933282,25 + 103111136620,75 + 334668704853,75 + 117503908192,25 = 875559682949)
Na taxa de migração atual, o equilíbrio será alcançado em cerca de 4,8 dias (815,4 GB ÷ 170,5 GB/dia ≈ 4,8 dias).
Etapa 5: Confirme se o fluxo da tarefa está bloqueado (remoção de shard)
Se uma tarefa de remoção de shard estiver bloqueada, a execução de sh.status() não exibirá migrações de chunks bem-sucedidas no histórico recente, e o shard de destino ainda conterá chunks não migrados. Isso impede a conclusão da tarefa e bloqueia outras operações de O&M no console do ApsaraDB for MongoDB.
O exemplo a seguir apresenta a saída típica do sh.status() para esse cenário.
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
Esse problema geralmente ocorre porque jumbo chunks bloqueiam a remoção do shard. Confirme essa condição executando o comando a seguir.
db.getSiblingDB("config").chunks.aggregate([{$match: {shard: "d-xxxxxxxxxxxxxx", jumbo:true}},{$group: {_id: "$ns", count: {$sum: 1}}}])
Os jumbo chunks geralmente resultam de um design inadequado da chave de shard (como hot keys). Teste as seguintes soluções:
Se a versão principal do seu MongoDB for a 4.4, use o comando refineCollectionShardKey para melhorar o design da chave de shard, adicionando sufixos para aumentar a cardinalidade e resolver os jumbo chunks.
Se a versão principal do seu MongoDB for a 5.0 ou posterior, use o comando reshardCollection para fazer o reshard da coleção com uma nova chave de shard. Para mais informações, consulte Fazer reshard de uma coleção.
Se for possível, exclua com segurança alguns dados de negócios e remova os dados do jumbo chunk. Isso reduz o tamanho dele e pode convertê-lo em um chunk regular que o Balancer consegue migrar.
Aumente o parâmetro
chunkSizepara alterar os critérios de detecção de jumbo chunks. Aplique esse ajuste apenas com a assistência da equipe de suporte técnico da Alibaba Cloud.
Se nenhum desses métodos funcionar, envie um ticket para entrar em contato com o suporte técnico.
Acelerar os processos de adição ou remoção
Para concluir a adição ou remoção de shards mais rapidamente, teste os seguintes métodos de aceleração:
Aumente a duração da janela do Balancer. Note que a migração de chunks adiciona carga extra que pode afetar o seu serviço. Avalie os riscos antes de fazer o ajuste. Para obter instruções, consulte gerencie o Balancer do MongoDB.
Para alterar a simultaneidade da migração de chunks, defina o parâmetro setParameter.chunkMigrationConcurrency. Para mais detalhes, consulte Recomendações de ajuste de parâmetros.
-
Para isso, execute manualmente as operações
moveChunkdurante os horários de menor pico. Para mais informações, consulte sh.moveChunk(). Exemplo:sh.moveChunk("<db>.<collection>", {"<shard_key>": <value>}, "d-xxxxxxxxxxxxx") // example: sh.moveChunk("records.people", { zipcode: "53187" }, "shard0019") envie um ticket para solicitar suporte técnico para o ajuste de parâmetros do kernel.