Explore o novo chatbot do Developer Center! O MongoDB AI chatbot pode ser acessado na parte superior da sua navegação para responder a todas as suas perguntas sobre o MongoDB .

Junte-se a nós no Amazon Web Services re:Invent 2024! Saiba como usar o MongoDB para casos de uso de AI .
Desenvolvedor do MongoDB
Central de desenvolvedor do MongoDBchevron-right
Produtoschevron-right
MongoDBchevron-right

Guia abrangente para otimizar o desempenho do MongoDB

Srinivas Mutyala7 min read • Published Jul 09, 2024 • Updated Jul 09, 2024
MongoDB
Ícone do FacebookÍcone do Twitterícone do linkedin
Avalie esse Artigo
star-empty
star-empty
star-empty
star-empty
star-empty
O MongoDB é conhecido por seu alto desempenho e escalabilidade, tornando-o uma escolha popular entre os bancos de dados NoSQL. No entanto, para aproveitar ao máximo seu potencial, é essencial ajustar a implantação do MongoDB. Este guia descreve várias estratégias e práticas recomendadas para melhorar o desempenho do MongoDB, abrangendo tudo, desde a identificação de gargalos até a otimização de queries e hardware.

Noções básicas sobre seu volume de trabalho

Antes de mergulhar no ajuste de desempenho, é crucial entender sua carga de trabalho. O desempenho do MongoDB pode variar significativamente com base no fato de seu aplicativo ter muita leitura, muitas gravações ou uma mistura balanceada. Utilize ferramentas como o Atlas Profilerdo MongoDB ou omongostat de código aberto para analisar suas operações de banco de dados e obter insights sobre seu volume de trabalho.

Indexação para desempenho

A indexação eficaz é uma das maneiras mais impactantes de melhorar o desempenho da consulta no MongoDB. Veja as principais práticas:
  • Crie índices relevantes: personalize os índices para corresponder aos padrões de consulta do seu aplicativo. Use o método [explain() para entender o comportamento da consulta e otimizar adequadamente.
db.collection.find({ field: value }).explain("executionStats")
Você também pode obter essas informações do MongoDB Compass com saída sofisticada, conforme mostrado abaixo.
Interface do MongoDB Compass mostrando a coleção 'addrInfo' dentro do banco de dados 'IndexDB'. A query { state: 'st1 ' } é inserida na barra de query. A interface exibe vários documentos com campos como ID, estado, cidade, pin, ponto de referência e lastModifiedOn. Os botões “Adicionar dados”, “Exportar dados”, “Atualizar” e “Excluir” estão visíveis abaixo da barra de consulta, junto com as opções para explicar a consulta, redefinir e encontrar documentos. A barra lateral esquerda lista outras coleções e bancos de dados.
Interface do Plano Explicativo do MongoDB Compass mostrando uma árvore visual do plano de execução da query. O diagrama inclui duas etapas: FETCH e IXSCAN. A etapa IXSCAN indica uma varredura de índice no índice 'state_1_city_1', com o documento 1 retornado e examinado, e nenhum índice multichave. A etapa FETCH mostra o mesmo documento retornado e o mesmo tempo de execução de 0 ms. O Resumo do Desempenho da Query à direita destaca 1 documento retornado, 1 documento examinado, 0 tempo de execução ms, não classificado na memória e 1 chave de índice examinada
  • Evite a indexação excessiva: embora os índices melhorem a velocidade da query, eles podem impedir operações de gravação e consumir espaço em disco adicional. Revise e remova regularmente índices não utilizados ou desnecessários.
db.collection.dropIndex("indexName")
  • Usar índices compostos: para consultas que envolvem vários campos, os índices compostos podem aumentar significativamente o desempenho.
db.collection.createIndex({ field1: 1, field2: -1 })

Otimizando padrões de consulta

Otimizar seus padrões de consulta é crucial para reduzir o tempo de execução e o uso de recursos:
  • Projeção: use a projeção para limitar os campos retornados por suas queries, minimizando a transferência de dados e a carga de processamento. Além disso, é melhor excluir ID com 0 (falso) se não for um campo referente ao aplicativo — ou seja, um campo gerado automaticamente pelo MongoDB. db.collection.find({ field: value }, { field1: 1, field2: 1 })
  • Framework deaggregation : aproveite o framework de aggregation do MongoDB para processamento de dados complexos. Certifique-se de que as agregações utilizem campos indexados sempre que possível.
db.collection.aggregate([ { $match: { field: value } }, { $group: { _id: "$field", total: { $sum: "$amount" } } } ])
  • Evitar $where: o operador$where pode ser lento e consome muitos recursos. Use-o com moderação e somente quando necessário. Em vez disso, o uso de $expr com operadores de agregação que não usam JavaScript (ou seja, operadores não $function e não $accumulator) é mais rápido do que $where porque não executa JavaScript e é preferível, quando possível. No entanto, se você precisar criar expressões personalizadas, $function é preferível a $where.

Considerações sobre hardware

O hardware no qual o MongoDB é executado desempenho um papel crucial em seu desempenho:
  • RAM: o MongoDB depende muito da RAM para armazenar conjuntos de trabalho. Se o seu conjunto de dados exceder a RAM disponível, considere atualizar a memória.
  • Armazenamento: utilize SSDs para armazenamento para melhorar a taxa de transferência de E/S e as velocidades de acesso a dados.
  • Rede: verifique se a largura de banda e a latência da rede são suficientes, especialmente em implantações distribuídas.

Replicação e fragmentação

Replicação e sharding O MongoDB oferece suporte à replicação e ao sharding para melhorar a disponibilidade e a escalabilidade:
  • Replicação: isso garante redundância de dados e alta disponibilidade. Configure as configurações de read preference para rotear com eficiência as operações de leitura entre réplicas. rs.initiate()
A seguir estão os métodos de leitura disponíveis com o MongoDB, que você pode configurar no nível do aplicativo.
  • ** primário ** : Lê somente do primário
  • primaryPreferred: lê do primário, se disponível, caso contrário, de um secundário
  • secundário: Lê apenas de um secundário
  • secondaryPreferred: lê de um secundário, se disponível, caso contrário, do primário
  • mais próximo: Lê do nó mais próximo com base na latência da rede e na integridade operacional
Exemplo: definir read preferences no código do aplicativo (Node.js)
1const MongoClient = require('mongodb').MongoClient;
2const uri = "mongodb://host1,host2,host3/?readPreference=secondaryPreferred";
3MongoClient.connect(uri, function(err, client) {
4 const db = client.db('test');
5 // Perform operations
6});
  • Fragmentação: distribui dados em vários servidores e é crucial para gerenciar grandes conjuntos de dados e operações de alto rendimento. Escolha uma chave de fragmento que distribua uniformemente os dados e a carga de consulta. sh.enableSharding("mydatabase") sh.shardCollection("mydatabase.mycollection", { shardKey: 1 })
Escolher uma chave de shard no MongoDB pode afetar significativamente o desempenho, dependendo se seu volume de trabalho é de leitura ou gravação. Aqui estão algumas diretrizes para selecionar uma chave de shard com base em sua carga de trabalho:
Cargas de trabalho de leitura intensiva
Seleção de chave de shard: escolha uma chave de shard que distribua uniformemente as operações de leitura entre os shards.
Considerações: use um campo de alta cardinalidade que garanta uma distribuição uniforme de leituras. Evite chaves de fragmento que podem causar pontos de acesso onde a maioria das leituras tem como alvo um único fragmento.
Exemplo: use um ID de usuário se as queries relacionadas ao usuário forem comuns.
sh.shardCollection("mydatabase.mycollection", { userID: 1 })
Volumes de trabalho com muitas gravações
Seleção de chave de shard: escolha uma chave de shard que equilibre a carga de gravação entre shards.
Considerações: Use um campo que mude com frequência e garanta uma distribuição uniforme da gravação. Evite aumentar monotonicamente as chaves (por exemplo, carimbos de data/hora), pois elas podem fazer com que um único fragmento se torne um gargalo.
Exemplo: use uma hashed shard key para distribuir as gravações uniformemente se você não conseguir obter uma chave de shard exclusiva.
sh.shardCollection("mydatabase.mycollection", { hashedField: "hashed" })
Considerações adicionais: Monitorar e ajustar: monitore continuamente o desempenho e ajuste as chaves de shard, se necessário.
Indexação: verifique se os índices estão alinhados com a chave de fragmento para obter o desempenho ideal da consulta. Ao selecionar a chave de fragmento apropriada e considerar a natureza de sua carga de trabalho, você pode otimizar sua implantação do MongoDB para operações de leitura e gravação.

Monitoramento e manutenção de desempenho

O monitoramento e a manutenção regulares são vitais para o desempenho sustentável:
  • Ferramentas de monitoramento: Utilize o MongoDB Atlas, mongostat e mongotop para monitorar o desempenho do banco de dados e o uso de recursos.
mongostat --host <host> mongotop --host <host>
  • Manutenção de rotina: compacte regularmente coleções, repare bancos de dados e rebalanceie fragmentos para garantir o desempenho ideal. db.repairDatabase()

Preocupações de leitura/gravação

A escolha da preocupação de gravação pode influenciar o desempenho e a durabilidade dos dados.

Desempenho

Uma write concern menor (por exemplo, w: 0) pode melhorar o desempenho reduzindo a latência da operação de escrita. No entanto, arrisca a durabilidade dos dados.
Impacto na latência
Preocupação de gravação inferior (por exemplo, w: 0):
Redução da latência:
  • O cliente não espera nenhuma confirmação do servidor.
  • A operação é enviada ao servidor e considerada concluída do ponto de vista do cliente.
  • Não há latência de ida e volta da rede, pois não há necessidade de o servidor responder.
Compensação:
  • Há um risco maior de perda de dados, pois o cliente não recebe nenhuma confirmação de sucesso na gravação.
  • Ele é adequado para dados não críticos ou cenários em que é necessária uma alta taxa de transferência de gravação com latência mínima.
Preocupação de gravação maior (por exemplo, w: 1 ou w: "maioria"):
Aumento da latência
  • O cliente aguarda a confirmação do servidor.
  • Para w: 1, aguarda a confirmação do nó primário.
  • Para w: "maioria", aguarda a confirmação da maioria dos nós do conjunto de réplicas.
  • A latência de ida e volta da rede e o tempo de processamento do servidor aumentam a latência geral.
  • Maior durabilidade e consistência de dados.
  • Garante que a operação de gravação seja replicada e reconhecida.
db.collection.insertOne({ field: "value" }, { writeConcern: { w: 1 } })

Preferências de leitura

A escolha da read preference pode influenciar o desempenho e a disponibilidade dos dados.
Desempenho: a distribuição de operações de leitura para nós secundários pode melhorar o desempenho reduzindo a carga no primary. Para distribuir com êxito as operações de leitura para nós secundários e, assim, melhorar o desempenho, é necessário definir a read preference no MongoDB. Aqui estão exemplos de como configurar read preferences:

MongoDB Shell

db.getMongo().setReadPref("secondaryPreferred")
URI de conexão
mongodb://host1,host2,host3/?readPreference=secondaryPreferred
** Exemplo de código do aplicativo (NodeJS) **
1const MongoClient = require('mongodb').MongoClient;
2const uri = "mongodb://host1,host2,host3/?readPreference=secondaryPreferred";
3MongoClient.connect(uri, function(err, client) {
4 const db = client.db('test');
5 // Perform operations
6})
Ao definir a read preference como secondaryPreferred, você direciona as operações de leitura para nós secundários quando elas estão disponíveis, reduzindo a carga no nó primary e melhorando o desempenho geral.
Verificações para identificar os motivos comuns para problemas de desempenho:
  • Execute o mongotop e o mongostat e verifique qual namespace está causando o problema.
  • Nível do sistema - verifique se há replicação primária. Há algum atraso e como está a oplog window?
  • Nível do aplicativo — verifique se há carregamentos em lote no nível do aplicativo.
  • Qualquer queries lentas (com currentOp ())?
  • Existem índices adequados?
  • Cluster fragmentado — a maioria das queries usa a chave de shard?
  • WT cache? Algum despejo?
  • Você vê contenção de gravação?
  • Abrir arquivos ( ulimit -a ) - 65000
  • Verifique se o processo mongod por si só causa carga no servidor ou qualquer outro processo.
  • top ou htop: Monitore o uso de CPU e memória do mongod e outros processos.
  • ps e grep: execute ps aux | grep mongod para visualizar o usodo recurso mongod .
  • iostat: Use iostat -x 1 10 para verificar as métricas de E/S do disco.
  • vmstat: execute vmstat 1 10 para obter instantâneos de desempenho geral do sistema.
Grave contenção no MongoDB. O lado esquerdo mostra uma única operação de atualização (db.col.updateOne()) resultando em uma nova versão do documento (v1 a v2) usando MVCC (Multi-Version Concurrency Control). O lado direito representa várias atualizações de documentos conflitantes (v2-1, v2-2, v2-3) com cruzes indicando operações com falha devido à contenção de escrita. Setas e ponteiros mostram o processo de atualizações e conflitos. O diagrama enfatiza como evitar a contenção de gravação revisando o design do esquema e destaca o uso do protocolo de simultaneidade otimista do storage engine WiredTiger.
A contenção de escrita no MongoDB pode ser identificada pelos seguintes indicadores:
Altas porcentagens de bloqueio: Use o mongostat para monitorar as porcentagens de bloqueio. Valores altos indicam contenção. Operações de gravação lenta: verifique se há operações de gravação lentas usando db.currentOp() que podem indicar contenção. Conflitos de gravação frequentes: revise os logs de mensagens sobre conflitos ou rejeições de gravação.
Aumento da latência: observe o aumento da latência em operações ou aplicativos de escrita pesada.
Exemplo de comando para monitorar porcentagens de bloqueio: mongostat --host <hostname>
Projetar o esquema adequadamente, como usar índices apropriados e evitar pontos de acesso com gravações distribuídas, pode ajudar a reduzir a contenção de gravação.

Conclusão

Obter o desempenho ideal do MongoDB envolve uma abordagem abrangente, incluindo otimização de queries, indexação adequada, recursos de hardware suficientes e monitoramento contínuo. Ao implementar as estratégias descritas neste guia, você pode melhorar significativamente a eficiência e a capacidade de resposta do MongoDB deployment, garantindo que ele atenda às solicitações de seus aplicativos.
Dúvidas? Comentários? Acesse o MongoDB Developer Community em seguida.
Principais comentários nos fóruns
Avatar do Comentarista do Fórum
Srinativas_MutyalaSrinativas Mutyalaúltimo trimestre

Olá comunidade !!!
Estou buscando suas sugestões/ feedback sobre este artigo.

Veja mais nos fóruns

Ícone do FacebookÍcone do Twitterícone do linkedin
Avalie esse Artigo
star-empty
star-empty
star-empty
star-empty
star-empty
Relacionado
Início rápido

Java – Criptografia no nível do campo do lado do cliente


Mar 01, 2024 | 14 min read
Tutorial

Adição de notificações em tempo real ao Ghost CMS usando MongoDB e eventos enviados pelo servidor


Aug 14, 2023 | 7 min read
Tutorial

O guia de 5 minutos para trabalhar com dados ESG no MongoDB


Aug 24, 2023 | 11 min read
Tutorial

Crie um blog moderno com Gatsby e MongoDB


Apr 02, 2024 | 16 min read
Sumário