A chave de shard ideal permite que o MongoDB distribua documentos uniformemente em todo o cluster, ao mesmo tempo em que facilita padrões de query comuns. Uma chave de shard abaixo do ideal pode levar a problemas de desempenho ou dimensionamento devido à distribuição desigual de dados. Você pode alterar a chave de fragmento de uma coleção para alterar a distribuição dos seus dados em um cluster.
A partir do MongoDB 8.0, você pode refragmentar uma coleção na mesma chave de fragmento, permitindo que você redistribua dados para incluir novos fragmentos ou em zonas diferentes sem alterar sua chave de fragmento. Para refragmentar na mesma chave de shard, defina forceRedistribution como true.
A partir do MongoDB 8.0.10, você pode refragmentar uma coleção de séries temporais. Todos os shards na coleção de séries temporais devem executar a versão 8.0.10 ou posterior para serem refragmentados.
Observação
Antes de refragmentar sua coleção, leia Solucionar problemas de chaves de Shard para obter informações sobre problemas comuns de desempenho e dimensionamento e conselhos sobre como corrigi-los.
Sobre esta tarefa
Somente uma coleção pode ser refragmentada de cada vez.
writeConcernMajorityJournalDefaultdeve sertrue.Para refragmentar uma collection que tenha uma restrição de exclusividade, a nova chave de shard deve satisfazer os requisitos de índice únicos para quaisquer índices únicos existentes.
Os comandos a seguir e os métodos de shell correspondentes não são compatíveis com a collection que está sendo refragmentada enquanto a operação de refragmentação está em andamento:
Se você executar uma das seguintes operações, ela aguardará até que a refragmentação seja concluída antes de ser executada:
dropDatabaseno banco de dados que hospeda a coleção que está passando por refragmentação
Se a collection que você está refragmentando usar MongoDB Search, o índice de pesquisa ficará indisponível quando a operação de refragmentação for concluída. Você precisa refragmentar manualmente o índice de pesquisa assim que a operação de refragmentação for concluída.
If the collection you're resharding is archived in Atlas Online Archives, the online archive files are marked as
Orphanedonce the resharding operation completes. You can create another online archive for the same database, collection, and fields as the orphaned archive as long as there is no other archive for that same combination in theActivestate.
Antes de começar
Antes de começar a refragmentar sua coleção, certifique-se de atender aos seguintes requisitos:
Seu aplicação pode tolerar um período de dois segundos em que a collection afetada bloqueia as gravações. Durante o período em que as gravações são bloqueadas, seu aplicação experimenta um aumento na latência.
Se sua carga de trabalho não tolerar esse requisito, considere ajustar sua chave de fragmento.
Seu banco de dados atende aos seguintes requisitos de recursos:
Certifique-se de que o espaço de armazenamento disponível em cada fragmento destinatário seja pelo menos duas vezes o tamanho de armazenamento da coleção que você deseja reparticionar os fragmentos mais seu tamanho de índice total, dividido pelo número de fragmentos:
( ( collection_storage_size + index_size ) * 2 ) / shard_count = storage_req Por exemplo, considere uma coleção com um tamanho de armazenamento de 2 TB de dados e um índice de 400 GB. Para distribuí-lo em quatro fragmentos, você precisa de:
( ( 2 TB collection + 0.4 TB index ) * 2 ) / 4 shards = 1.2 TB storage Para refragmentar esta coleção, cada fragmento requer 1.2 TB de armazenamento disponível.
No MongoDB Atlas, talvez seja necessário atualizar para o próximo tier de armazenamento para a operação de refragmentação. Você pode fazer o downgrade assim que a operação for concluída.
Certifique-se de que sua capacidade de E/S esteja abaixo de 50%.
Certifique-se de que a carga da CPU esteja abaixo de 80%.
Importante
Esses requisitos não são exigidos pelo banco de dados. Uma falha na alocação de recursos suficientes pode resultar em:
o banco de dados ficar sem espaço e desligando
redução do desempenho
a operação demora mais que o esperado
Se o seu aplicação tiver períodos com menos tráfego, execute esta operação na coleção durante esse período, se possível.
Você não precisa criar um índice na nova chave de fragmento antes de refragmentar. A operação de refragmentação cria os índices necessários automaticamente durante a fase de indexação.
Nenhuma construção de índice está em andamento. Para verificar se há construções de índice em execução, use
$currentOp:db.getSiblingDB("admin").aggregate( [ { $currentOp : { idleConnections: true } }, { $match: { $or: [ { "op": "command", "command.createIndexes": { $exists: true } }, { "op": "none", "msg": /^Index Build/ } ] } } ] ) No documento de resultado, se o valor do campo
inprogfor uma array vazia, não haverá nenhuma construção de índice em andamento:{ inprog: [], ok: 1, '$clusterTime': { ... }, operationTime: <timestamp> }
Observação
Uma operação de refragmentação é um processo de gravação intensiva que pode gerar taxas maiores de oplog. Talvez você queira:
definir um tamanho fixo de oplog para prevenir o crescimento ilimitado do oplog.
aumentar o tamanho do oplog para minimizar a chance de um ou mais nós secundários se tornarem obsoletos.
Consulte a documentação Conjunto de réplicas do Oplog para obter mais detalhes.
Protocolo de gravar em duas fases
Queries que não incluem a chave de shard com hash completa no filtro de queries podem exigir um protocolo de gravação de duas fases. Este protocolo transmite a query para múltiplos shards e pode reduzir significativamente o desempenho.
As query que fornecem a chave de shard com hash antiga em vez da nova chave de shard com hash usam o protocolo de gravar de duas fases.
O método
deleteOne()usa o protocolo de gravação de duas fases quando o filtro de queries não usa a chave de shard com hash completa ou o campo_id.Os métodos
replaceOne()eupdateOne():Quando a query fornece a chave de shard com hash completa, o protocolo de duas fases nunca é usado.
Quando a query não fornece a chave de shard com hash completa, mas fornece o campo
_id, o uso do protocolo de gravação de duas fases depende do valor deupsert. Seupsertestiver definido comotrue, o protocolo de gravar de duas fases será utilizado. Seupsertforfalse, o protocolo de gravar de duas fases não é usado.Quando a query não fornece nem a chave de shard com hash completa nem o campo
_id, o protocolo de gravação de duas fases é sempre usado.
Os métodos a seguir usam o protocolo de gravar de duas fases quando o filtro de queries não usa a chave de shard com hash completa:
Para otimizar o desempenho, atualize seu aplicativo após a conclusão da operação de resharding para usar a nova chave de shard com hash em filtros de queries para essas operações.
Passos
Importante
É altamente recomendável que você verifique a seção Sobre esta tarefa e leia a seção Etapas na íntegra antes de refragmentar sua collection.
Em uma operação de refragmentação de collection, um fragmento (shard) pode ser um:
doador, que atualmente armazena chunks para a coleção fragmentada.
receptor, que armazena novos chunks para a coleção fragmentada com base nas chaves de fragmento e nas zonas.
Um shard pode ser doador e um receptor ao mesmo tempo.
O servidor de configuração primário é sempre o gerenciador de refragmentação e inicia cada fase da operação de refragmentação.
Desabilitar o balancer
You must turn off the balancer before you begin the process of resharding a collection. To disable the balancer, see here.
Inicie a operação de refragmentação.
Enquanto conectado ao mongos, emita um comando reshardCollection que especifica a collection a ser refragmentada e a nova chave de shard:
db.adminCommand({ reshardCollection: "<database>.<collection>", key: <shardkey> })
O MongoDB define o número máximo de segundos para bloquear gravações para dois segundos e inicia a operação de refragmentação.
Para refragmentar na mesma chave de shard, defina forceRedistribution como true:
db.adminCommand({ reshardCollection: "<database>.<collection>", key: <shardkey>, forceRedistribution: true })
Você também pode usar sh.reshardCollection() para refragmentar uma collection com a mesma chave. Para obter um exemplo, consulte Redistribuir dados para novos fragmentos.
Monitore a operação de refragmentação.
Para monitorar a operação de refragmentação, você pode usar o estágio de pipeline$currentOp:
db.getSiblingDB("admin").aggregate([ { $currentOp: { allUsers: true, localOps: false } }, { $match: { type: "op", "originatingCommand.reshardCollection": "<database>.<collection>" } } ])
Observação
Para ver os valores atualizados, você precisa executar continuamente o pipeline anterior.
As saídas do pipeline $currentOp:
totalOperationTimeElapsedSecs: tempo de operação decorrido em segundosremainingOperationTimeEstimatedSecs: estimated time remaining in seconds for the current resharding operation. It is returned as-1when a new resharding operation starts.A partir do MongoDB 7.0,
remainingOperationTimeEstimatedSecstambém está disponível no coordenador durante uma operação de refragmentação.remainingOperationTimeEstimatedSecsestá definido para uma estimativa de tempo pessimista:A estimativa de tempo da fase de recuperação é definida como o tempo da fase de clonagem, que é um tempo relativamente longo.
Na prática, se houver apenas algumas operações de escrita pendentes, o tempo de fase de recuperação real é relativamente curto.
[ { shard: '<shard>', type: 'op', desc: 'ReshardingRecipientService | ReshardingDonorService | ReshardingCoordinatorService <reshardingUUID>', op: 'command', ns: '<database>.<collection>', originatingCommand: { reshardCollection: '<database>.<collection>', key: <shardkey>, unique: <boolean>, collation: { locale: 'simple' } }, totalOperationTimeElapsedSecs: <number>, remainingOperationTimeEstimatedSecs: <number>, ... }, ... ]
Reabilitar o balanceador.
To enable the balancer, see here.
Comportamento
Duração mínima de uma operação de refragmentação
A duração mínima de uma operação de refragmentação é sempre de cinco minutos.
Gravações repetíveis
As Retryable Writes iniciadas antes ou durante a refragmentação podem ser repetidas durante e após a collection ter sido refragmentada por até cinco minutos. Após cinco minutos, talvez você não consiga encontrar o resultado definitivo da gravação e as tentativas subsequentes de repetir a gravação falharão com o erro IncompleteTransactionHistory.
Limitações de refragmentação
If the collection uses Atlas Search, the search index becomes unavailable after the operation completes. To restore it, manually rebuild the search index.
Coleções que usam queryable encryption não são suportadas.
Erro de Case
Duplicate _id Values
A operação de refragmentação falhará se _id valores não forem globalmente exclusivos para evitar a corrupção dos dados da collection. Valores _id duplicados também podem impedir a migração bem-sucedida de chunks. Se houver documentos com valores _id duplicados, copie os dados de cada um deles em um novo documento e, em seguida, exclua os documentos duplicados.