Construção contínua de índices em clusters fragmentados
A criação de índices pode afetar o desempenho do cluster fragmentado. Por padrão, o MongoDB cria índices simultaneamente em todos os membros do conjunto de réplicas que contém dados. As compilações de índice em clusters fragmentados ocorrem apenas nos fragmentos que contêm dados para a coleção que está sendo indexada. Para cargas de trabalho que não toleram redução no desempenho devido à compilação de índices, considere usar o procedimento a seguir para criar índices de forma contínua.
As construções de índice contínuo retiram no máximo um membro do conjunto de réplicas de fragmento de cada vez, começando pelos membros secundários, e criam o índice nesse membro como autônomo. As compilações de índice contínuo exigem pelo menos uma eleição de conjunto de réplicas por fragmento.
Observação
Para obter informações sobre como criar índices no Atlas, consulte a página degerenciamento de índice do na documentação do Atlas .
Considerações
Unique Indexes
Para criar índices únicos usando o procedimento a seguir, você deve parar todas as gravações da coleção durante o procedimento.
Se não for possível parar todos os escritos na coleção durante este procedimento, não use o procedimento nesta página. Em vez disso, crie seu índice único na coleção emitindo db.collection.createIndex()
no mongos
para um cluster fragmentado.
Tamanho do log
Certifique-se de que seu oplog seja grande o suficiente para permitir que a operação de indexação ou reindexação seja concluída sem ficar muito para trás para recuperar o atraso. Consulte a documentação de dimensionamento do oplog para obter informações adicionais.
Pré-requisitos
- Para construir índices únicos
Para criar índices únicos usando o procedimento a seguir, você deve interromper todas as gravações na collection durante a compilação do índice. Caso contrário, você pode acabar com dados inconsistentes nos conjuntos de réplicas. Se não for possível parar todas as gravações na collection, não use o procedimento a seguir para criar índices únicos.
Aviso
Se não for possível parar todos os escritos na coleção, não use o procedimento a seguir para criar índices únicos.
Antes de criar o índice, valide se nenhum documento na collection viola as restrições do índice. Se uma collection for distribuída entre shards e um shard contiver um chunk com documentos duplicados, a operação de criação de índice poderá ser bem-sucedida nos shards sem duplicatas, mas não no shard com duplicatas. Para evitar deixar índices inconsistentes entre shards, você pode emitir o
db.collection.dropIndex()
de ummongos
para descartar o índice da collection.
Procedimento
Importante
O procedimento a seguir para criar índices de forma contínua se aplica a implantações de cluster fragmentados e não a implantações de conjuntos de réplicas. Para obter o procedimento para o conjunto de réplicas, consulte Construção contínua de índices no Conjunto de réplicas.
A. Pare o balanceador
Conecte o mongosh
a uma instância do mongos
no cluster fragmentado e execute o sh.stopBalancer()
para desabilitar o balanceador: [1]
sh.stopBalancer()
Observação
Se houver uma migração em andamento, o sistema a concluirá antes de encerrar o balancer.
Para verificar se o balanceador está desativado, execute sh.getBalancerState()
, que retorna falso se o balanceador estiver desativado:
sh.getBalancerState()
[1] | A partir do MongoDB 4.2, sh.stopBalancer() também desabilita a divisão automática para o cluster fragmentado. |
B. Determinar a distribuição da coleção
A partir de mongosh
conectado ao mongos
, atualize a tabela de roteamento em cache para esse mongos
para evitar o retorno de informações de distribuição obsoletas para a coleção. Depois de atualizado, execute db.collection.getShardDistribution()
para a coleção na qual deseja construir o índice.
Por exemplo, se você quiser criar um índice ascendente na collection records
no banco de dados test
:
db.adminCommand( { flushRouterConfig: "test.records" } ); db.records.getShardDistribution();
O método produz a distribuição de fragmentos. Por exemplo, considere um cluster fragmentado com 3 fragmentos shardA
, shardB
e shardC
e o db.collection.getShardDistribution()
retorna o seguinte:
Shard shardA at shardA/s1-mongo1.example.net:27018,s1-mongo2.example.net:27018,s1-mongo3.example.net:27018 data : 1KiB docs : 50 chunks : 1 estimated data per chunk : 1KiB estimated docs per chunk : 50 Shard shardC at shardC/s3-mongo1.example.net:27018,s3-mongo2.example.net:27018,s3-mongo3.example.net:27018 data : 1KiB docs : 50 chunks : 1 estimated data per chunk : 1KiB estimated docs per chunk : 50 Totals data : 3KiB docs : 100 chunks : 2 Shard shardA contains 50% data, 50% docs in cluster, avg obj size on shard : 40B Shard shardC contains 50% data, 50% docs in cluster, avg obj size on shard : 40B
A partir da saída, você somente constrói os índices para test.records
em shardA
e shardC
.
C. Criar índices nos shards que contêm chunks da collection
Para cada fragmento que contém blocos para a coleção, siga o procedimento para construir o índice no fragmento.
C1. Parar um secundário e reiniciar como autônomo
Para um fragmento afetado, interrompa o processo mongod
associado a um de seus fragmentos secundários. Reinicie após fazer as seguintes atualizações de configuração:
Se você estiver usando um arquivo de configuração, faça as seguintes atualizações de configuração:
Altere o
net.port
para uma porta diferente. [2] Anote a configuração da porta original como comentário.Comente a opção
replication.replSetName
.Comente a opção
sharding.clusterRole
.Defina o parâmetro
skipShardingConfigurationChecks
comotrue
na seçãosetParameter
.Defina o parâmetro
disableLogicalSessionCacheRefresh
comotrue
na seçãosetParameter
.
Por exemplo, para um membro do conjunto de réplicas de shard, o arquivo de configuração atualizado incluirá conteúdo como o seguinte exemplo:
net: bindIp: localhost,<hostname(s)|ip address(es)> port: 27218 # port: 27018 #replication: # replSetName: shardA #sharding: # clusterRole: shardsvr setParameter: skipShardingConfigurationChecks: true disableLogicalSessionCacheRefresh: true
E reinicie:
mongod --config <path/To/ConfigFile>
Outras configurações (por exemplo storage.dbPath
, etc.) permanecem inalteradas.
Se estiver usando opções de linha de comando, faça as seguintes atualizações de configuração:
Remova
--replSet
.Remova
--shardsvr
se for um membro do shard e--configsvr
se for um membro do servidor de configuração .Configure o parâmetro
skipShardingConfigurationChecks
paratrue
na opção--setParameter
.Configure o parâmetro
disableLogicalSessionCacheRefresh
paratrue
na opção--setParameter
.
Por exemplo, reinicie o membro do conjunto de réplicas de fragmentos sem as opções --replSet
e --shardsvr
. Especifique um novo número de porta e defina os parâmetros skipShardingConfigurationChecks
e disableLogicalSessionCacheRefresh
como verdadeiro:
mongod --port 27218 --setParameter skipShardingConfigurationChecks=true --setParameter disableLogicalSessionCacheRefresh=true
Outras configurações (por exemplo --dbpath
, etc.) permanecem inalteradas.
[2] | (1, 2) Ao executar o mongod em uma porta diferente, você garante que os outros membros do conjunto de réplicas e todos os clientes não entrem em contato com o membro enquanto você estiver construindo o índice. |
C2. Construir o Índice
Conecte-se diretamente à instânciamongod
em execução como standalone na nova porta e crie o novo índice para essa instância.
Por exemplo, conecte mongosh
à instância e use o método db.collection.createIndex()
para criar um índice ascendente no campo username
da coleção records
:
db.records.createIndex( { username: 1 } )
C3. Reinicie o programa mongod
como um membro do conjunto de réplicas
Quando a criação do índice for concluída, encerre a instância mongod
. Desfaça as alterações de configuração feitas ao iniciar como standalone para retornar à configuração original e reiniciar.
Importante
Certifique-se de remover o parâmetro skipShardingConfigurationChecks
e o parâmetro disableLogicalSessionCacheRefresh
.
Por exemplo, para reiniciar o membro do fragmento do seu conjunto de réplicas:
Se você estiver usando um arquivo de configuração:
Reverta para o número da porta original.
Descomente o
replication.replSetName
.Descomente o
sharding.clusterRole
.Remova o parâmetro
skipShardingConfigurationChecks
na seçãosetParameter
.Remova o parâmetro
disableLogicalSessionCacheRefresh
da seçãosetParameter
.
net: bindIp: localhost,<hostname(s)|ip address(es)> port: 27018 replication: replSetName: shardA sharding: clusterRole: shardsvr
Outras configurações (por exemplo storage.dbPath
, etc.) permanecem inalteradas.
E reinicie:
mongod --config <path/To/ConfigFile>
Se você estiver usando opções da linha de comando:
Reverta para o número da porta original.
Inclua
--replSet
.Inclua
--shardsvr
se for um membro do fragmento ou--configsvr
se for um membro do servidor de configuração.Remove parameter
skipShardingConfigurationChecks
.Remove parameter
disableLogicalSessionCacheRefresh
.
Por exemplo:
mongod --port 27018 --replSet shardA --shardsvr
Outras configurações (por exemplo --dbpath
, etc.) permanecem inalteradas.
Permitir que a replicação alcance este membro.
C4. Repetir o procedimento para os secundários restantes para o shard
Quando o membro alcançar os outros membros do conjunto, repita o procedimento um membro por vez para os membros secundários restantes para o fragmento:
C5. Construa o índice no primário
Quando todos os secundários do fragmento tiverem o novo índice, retire o primário do fragmento, reinicie-o como autônomo usando o procedimento descrito acima e crie o índice no primário anterior:
Use o método
rs.stepDown()
emmongosh
para reduzir o primário. Após a redução bem-sucedida, o primário atual se torna secundário e os nós do conjunto de réplicas elegem um novo primário.C3. Reinicie o programa
mongod
como um membro do conjunto de réplicas
D. Repetir para os outros fragmentos afetados
Quando terminar de construir o índice para um fragmento, repita C. Construir índices nos fragmentos que contêm partes de coleção para os outros fragmentos afetados.
E. Reinicie o Balanceador
Quando terminar a construção contínua do índice para os shards afetados, reinicie o balancer.
Conecte mongosh
a uma instância mongos
no cluster fragmentado e execute sh.startBalancer()
: [3]
sh.startBalancer()
[3] | A partir do MongoDB 4.2, o sh.startBalancer() também habilita a divisão automática para o cluster fragmentado. |
Informações adicionais
Uma collection fragmentada terá um índice inconsistente se a coleção não tiver exatamente os mesmos índices (inclusive as opções de índice) em cada shard que contiver blocos para a coleção. Embora os índices inconsistentes não devam ocorrer durante as operações normais, podem ocorrer, por exemplo:
Quando um usuário está criando um índice com uma restrição de chave
unique
e um fragmento contém um bloco com documentos duplicados. Nesses casos, a operação de criação do índice pode ser bem-sucedida nos fragmentos sem duplicatas, mas não no fragmento com duplicatas.Quando um usuário está criando um índice entre os fragmentos de forma contínua, mas não consegue criar o índice para um fragmento associado ou cria incorretamente um índice com uma especificação diferente.
O servidor de configuração primário verifica periodicamente se há inconsistências de índice nos fragmentos das coleções fragmentadas. Para configurar essas verificações periódicas, consulte enableShardedIndexConsistencyCheck
e shardedIndexConsistencyCheckIntervalMS
.
O comando serverStatus
retorna o campo shardedIndexConsistency
para relatar inconsistências de índice quando executado no servidor de configuração primário.
Para verificar se uma collection fragmentada tem índices inconsistentes, consulte Localizar índices inconsistentes em shards.