Atualização: abril de 2018
Esta resposta estava correta no momento da pergunta, mas as coisas mudaram desde então. Desde que o paralelismo da versão 3.4 foi introduzido, e o ticket que referi originalmente foi fechado. Para mais informações, abordo alguns dos detalhes desta resposta mais recente . Deixarei o restante da resposta como está, porque ela continua sendo uma boa referência para problemas / restrições gerais, além de ser válida para qualquer pessoa em uma versão mais antiga.
Resposta original
Dou uma explicação completa do que acontece com uma migração de partes no curso M202 Advanced, se você estiver interessado. Em termos gerais, digamos apenas que as migrações não são muito rápidas, mesmo para trechos vazios, por causa da limpeza sendo executada para garantir que as migrações funcionem em um sistema ativo (elas ainda acontecem mesmo que nada além de balanceamento esteja acontecendo).
Além disso, há apenas uma migração acontecendo por vez em todo o cluster - não há paralelismo. Portanto, apesar de você ter dois nós "completos" e dois nós "vazios", a qualquer momento, ocorre no máximo uma migração (entre o shard com mais chunks e o shard com menos). Portanto, ao adicionar 2 shards, você não ganha nada em termos de velocidade de balanceamento e apenas aumenta o número de pedaços que precisam ser movidos.
Para as próprias migrações, é provável que os chunks tenham aproximadamente 30MiB de tamanho (depende de como você preencheu os dados, mas geralmente essa será sua média com o tamanho máximo padrão de chunk). Você pode executar db.collection.getShardDistribution()
algumas dessas informações e ver minha resposta aqui para obter mais informações sobre seus blocos.
Como não há outra atividade em andamento, para que uma migração aconteça, o shard de destino (um dos shards adicionados recentemente) precisará ler ~ 30MiB de dados dos shards de origem (um dos 2 originais) e atualizar os servidores de configuração para refletem o novo local do pedaço depois de concluído. Mover 30MiB de dados não deve ser um gargalo para um sistema normal sem carga.
Se estiver lento, existem várias razões possíveis para que isso aconteça, mas as mais comuns para um sistema que não está ocupado são:
- E / S do disco de origem - se os dados não estiverem na memória ativa quando forem lidos, deverão ser paginados do disco
- Rede - se houver latência, limitação de taxa, perda de pacotes etc., a leitura poderá demorar um pouco
- E / S de disco de destino - os dados e os índices precisam ser gravados no disco, muitos índices podem piorar as coisas, mas geralmente isso não é um problema em um sistema com pouca carga
- Problemas com migrações que causam interrupções e falhas de migração (problemas com servidores de configuração, problemas com exclusões em primárias)
- Atraso de replicação - para migrações para conjuntos de réplicas, preocupação com gravação
w:2
ou w:majority
é usado por padrão e requer secundárias atualizadas para satisfazê-lo.
Se o sistema estivesse ocupado, a contenção de memória também seria suspeita de contenção de bloqueio.
Para obter mais informações sobre quanto tempo as migrações estão demorando, se estão falhando, etc., consulte as entradas em config.changelog
:
// connect to mongos
use config
db.changelog.find()
Como você viu, e como geralmente digo às pessoas quando faço treinamento / educação, se você sabe que precisará de 4 fragmentos, geralmente é melhor começar com 4 em vez de acelerar. Se o fizer, precisará estar ciente de que a adição de um fragmento pode levar muito tempo e, inicialmente, é um negativo líquido de recursos, e não um ganho (consulte a parte II da minha série de armadilhas de fragmentação para uma discussão mais detalhada sobre isso).
Por fim, para acompanhar / votar / comentar sobre a solicitação de recurso para melhorar o paralelismo das migrações de chunk, consulte o SERVER-4355