Estamos usando o MongoDB há várias semanas, a tendência geral que vimos foi que o mongodb está usando muita memória (muito mais do que todo o tamanho de seu conjunto de dados + índices).
Eu já li essa pergunta e essa pergunta , mas nenhuma parece abordar o problema que estou enfrentando; na verdade, elas estão explicando o que já foi explicado na documentação.
A seguir estão os resultados dos comandos htop e show dbs .
Eu sei que o mongodb usa E / S mapeada na memória, portanto, basicamente, o sistema operacional lida com o armazenamento em cache de coisas na memória, e o mongodb deveria, teoricamente, deixar sua memória em cache quando outro processo solicitar memória livre , mas pelo que vimos, isso não acontece.
OOM começa e acaba com outros processos importantes, como postgres, redis etc. (Como pode ser visto, para superar esse problema, aumentamos a RAM para 183 GB, que agora funciona, mas é bastante cara. O mongo está usando ~ 87 GB de RAM, quase 4X do tamanho de todo o conjunto de dados)
Tão,
- Essa quantidade de memória é realmente esperada e normal? (De acordo com a documentação, o WiredTiger usa no máximo ~ 60% da RAM para seu cache, mas considerando o tamanho do conjunto de dados, ele possui dados suficientes para conseguir 86 GB de RAM?)
- Mesmo que o uso de memória seja esperado, por que o mongo não larga sua memória alocada, caso outro processo comece a solicitar mais memória? Vários outros processos em execução estavam sendo constantemente eliminados pelo linux oom, incluindo o próprio mongodb, antes de aumentarmos a RAM e tornar o sistema totalmente instável.
Obrigado !
fonte
Respostas:
Ok, depois de seguir as dicas dadas por loicmathieu e jstell e desenterrá-las um pouco, essas são as coisas que descobri sobre o MongoDB usando o mecanismo de armazenamento WiredTiger. Estou colocando aqui se alguém encontrou as mesmas perguntas.
Os threads de uso de memória que mencionei pertenceram a 2012-2014, todos anteriores ao WiredTiger e estão descrevendo o comportamento do mecanismo de armazenamento MMAPV1 original que não possui um cache ou suporte à compactação separado.
As configurações de cache do WiredTiger controlam apenas o tamanho da memória usada diretamente pelo mecanismo de armazenamento WiredTiger (não a memória total usada pelo mongod). Muitas outras coisas estão potencialmente ocupando memória em uma configuração do MongoDB / WiredTiger, como as seguintes:
O WiredTiger compacta o armazenamento em disco, mas os dados na memória não são compactados.
O WiredTiger, por padrão, não sincroniza os dados em cada confirmação , portanto os arquivos de log também estão na RAM, o que afeta sua memória. Também é mencionado que, para usar E / S com eficiência, os WiredTiger dividem as solicitações de E / S (falhas de cache) juntas, o que também parece consumir RAM (na verdade, páginas sujas (páginas que foram alteradas / atualizadas) têm uma lista de atualizações armazenadas em uma SkipList simultânea ).
O WiredTiger mantém várias versões de registros em seu cache (controle de simultaneidade de várias versões , as operações de leitura acessam a última versão confirmada antes da operação).
WiredTiger Mantém as somas de verificação dos dados no cache.
-Se MongoDB consome memória para lidar com conexões abertas, agregações, código serverside e etc .
Considerando esses fatos, confiar
show dbs;
não era tecnicamente correto, pois mostra apenas o tamanho compactado dos conjuntos de dados.Os seguintes comandos podem ser usados para obter o tamanho completo do conjunto de dados.
Este resultado é o seguinte:
Portanto, parece que o tamanho real do conjunto de dados + seus índices estão consumindo cerca de 68 GB dessa memória.
Considerando tudo isso, acho que o uso de memória agora é bastante esperado, sendo uma boa parte limitar completamente o tamanho do cache do WiredTiger, já que ele lida com operações de E / S com bastante eficiência (como descrito acima).
Também existe o problema da OOM, para superar esse problema, como não tínhamos recursos suficientes para remover o mongodb, reduzimos o oom_score_adj para impedir que a OOM matasse processos importantes por enquanto (o que significa que dissemos à OOM para não matar nossa processos desejados ).
fonte
oom_score_adj
solução foi a melhor coisa que você conseguiu criar?Eu não acho que você tenha um problema aqui com o MongoDB, como jstell disse que o MongoDB com WiredTiger usará 50% da memória disponível; portanto, se você aumentar a RAM do seu servidor, será necessário mais memória.
Por que é mais do que o tamanho dos índices DB +, lembre-se de que o WiredTiger compacta o banco de dados no disco e também usa logs de instantâneo para registrar alterações de documentos. Portanto, o tamanho real do WiredTiger é o tamanho usando show dbs *pression_ration + tamanho dos logs de captura instantânea. Portanto, é quase impossível saber o tamanho exato esperado.
Mantenha também em mente que ferramentas como
top
,ps
,htop
não exibir a memória realmente usada pelo aplicativo,, comunique a esta pergunta SOW para mais detalhes: https://stackoverflow.com/questions/131303/how-to-measure-actual-memory -usage-of-an-application-or-processAgora, volte ao seu problema. Você tem outras ferramentas em execução no mesmo host e um OOM as mata. Eu não estou familiarizado com o Linux OOM, mas você tem certeza de que ele os mata por causa do MongoDB ou .. apenas por causa deles (talvez mate o Postgres porque o Postgres consumiu muita memória).
De qualquer forma, como prática recomendada se você tiver um grande banco de dados Mongo, não o instale em um host compartilhado com outros bancos de dados ou você terá muitas dificuldades, caso haja um problema como o que você descreve aqui, para saber que realmente causam o problema no host.
fonte
Documentos
Você pode ler as preocupações básicas de memória do MongoDB e também esta breve discussão sobre a verificação do uso da memória .
Visão geral do uso de memória
O comando
db.serverStatus()
( docs ) pode fornecer uma visão geral do uso da memória, especificamente:Qual é o tamanho dos seus índices?
db.stats()
pode mostrar o tamanho total de todos os índices, mas também podemos obter informações detalhadas de uma única coleção usandodb.myCollection.stats()
Por exemplo, este comando irá comparar os tamanhos dos índices para cada coleção :
Agora podemos ver os detalhes dessa coleção massiva, para ver quais de seus índices são os mais caros:
Isso pode nos dar uma idéia melhor de onde é possível economizar.
(Nesse caso, tínhamos um índice
createTime
bastante grande - uma entrada por documento - e decidimos que poderíamos viver sem ele.)fonte
createTime
índice era problemático porque era único para cada documento e essa coleção era enorme. A indexação dos outros campos estava correta, porque havia menos valores exclusivos (os valores foram agrupados).