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 o tamanho total de seu conjunto de dados + índices).
Eu já li esta pergunta e esta pergunta , mas nenhuma parece resolver o problema que estou enfrentando, eles estão realmente explicando o que já está explicado na documentação.
A seguir estão os resultados dos comandos htop e show dbs .
Eu sei que o mongodb usa IO mapeado na memória, então basicamente o sistema operacional lida com o cache de coisas na memória, e o mongodb teoricamente deve liberar sua memória em cache quando outro processo solicitar memória livre , mas pelo que vimos, isso não acontece.
OOM entra em ação e começa a matar 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 é muito caro. quase 4X do tamanho de todo o seu conjunto de dados)
Então,
- Esse uso de memória é realmente esperado e normal? (De acordo com a documentação, o WiredTiger usa no máximo ~ 60% de RAM para seu cache, mas considerando o tamanho do conjunto de dados, ele tem dados suficientes para poder levar 86 GB de RAM?)
- Mesmo que o uso de memória seja esperado, por que o mongo não libera 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 isso tornava o sistema totalmente instável.
Obrigado !
Ok, então depois de seguir as pistas dadas por loicmathieu e jstell, e cavar 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, todos pertenciam 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 separado ou suporte para compactação.
As configurações de cache do WiredTiger controlam apenas o tamanho da memória usada diretamente pelo mecanismo de armazenamento do WiredTiger (não a memória total usada pelo mongod). Muitas outras coisas estão potencialmente consumindo 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 são descompactados.
O WiredTiger, por padrão, não sincroniza os dados em cada commit , portanto, os arquivos de log também estão na RAM, o que afeta a memória. Também é mencionado que, para usar a E/S com eficiência, o WiredTiger agrupa as solicitações de E/S (faltas de cache), o que também parece consumir alguma RAM (na verdade, as páginas sujas (páginas que foram alteradas/atualizadas) têm uma lista de atualizações neles armazenados em um Concurrent SkipList ).
O WiredTiger mantém várias versões de registros em seu cache (Multi Version Concurrency Control, operações de leitura acessam a última versão confirmada antes de sua operação).
WiredTiger Mantém as somas de verificação dos dados em cache.
O próprio MongoDB consome memória para lidar com conexões abertas, agregações, código do lado do servidor e etc.
Considerando esses fatos, confiar em
show dbs;
não foi tecnicamente correto, pois mostra apenas o tamanho compactado dos conjuntos de dados.Os comandos a seguir podem ser usados para obter o tamanho total do conjunto de dados.
Este resultado é o seguinte:
Portanto, parece que o tamanho real do conjunto de dados + seus índices estão ocupando cerca de 68 GB dessa memória.
Considerando tudo isso, acho que o uso de memória agora é bastante esperado, sendo que não há problema em limitar o tamanho do cache do WiredTiger, pois ele lida com operações de E/S de maneira bastante eficiente (conforme descrito acima).
Também permanece o problema do OOM, para superar esse problema, já que não tínhamos recursos suficientes para eliminar o mongodb, baixamos o oom_score_adj para evitar que o OOM matasse processos importantes por enquanto (o que significa que dissemos ao OOM para não matar nosso processos desejados ).
Documentos
Você pode gostar de ler as preocupações básicas de memória para o MongoDB e também esta breve discussão sobre como verificar o 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 de memória, especificamente:Quando tivemos um problema de RAM, foi porque um de nossos índices estava ocupando muita RAM. Então, aqui vou mostrar como nós rastreamos isso.
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 para uma única coleção usandodb.myCollection.stats()
Por exemplo, este comando irá comparar os tamanhos dos índices para cada coleção :
Agora podemos analisar os detalhes dessa coleção massiva, para ver quais de seus índices são os mais caros:
Isso pode nos dar uma ideia melhor de onde a economia pode ser possível.
(Neste caso, tínhamos um índice
createTime
bastante grande - uma entrada por documento - e decidimos que poderíamos viver sem ele.)Eu não acho que você tenha um problema aqui com o MongoDB, como jstell lhe disse que o MongoDB com WiredTiger usará 50% da memória disponível, portanto, se você aumentar a RAM do seu servidor, levará mais memória.
Por ser mais do que o tamanho do DB + índices, lembre-se de que o WiredTiger compacta o banco de dados no disco e também usa logs de instantâneos para registrar as alterações do documento. Portanto, o tamanho real do WiredTiger é o tamanho usando show dbs * compression_ration + size of snapshot logs. Portanto, é quase impossível saber o tamanho exato esperado.
Lembre-se também de que ferramentas como
top
,ps
,htop
não exibiam a memória realmente usada pelo aplicativo, consulte esta pergunta SOW para obter detalhes: https://stackoverflow.com/questions/131303/how-to-measure-actual-memory -uso-de-um-aplicativo-ou-processoAgora, de volta 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 tomou muita memória).
De qualquer forma, como melhor prática se você tiver um grande banco de dados Mongo, não o instale em um host compartilhado com outros bancos de dados ou terá muitas dificuldades, caso ocorra um problema como o que você descreve aqui, para saber que realmente causam o problema no host.