O MongoDB termina quando fica sem memória

11

Eu tenho a seguinte configuração:

  • uma máquina host que executa três contêineres de encaixe:
    • MongoDB
    • Redis
    • Um programa usando os dois contêineres anteriores para armazenar dados

Redis e MongoDB são usados ​​para armazenar grandes quantidades de dados. Eu sei que o Redis precisa manter todos os seus dados na RAM e estou bem com isso. Infelizmente, o que acontece é que o mongo começa a ocupar muita RAM e, assim que a RAM do host estiver cheia (estamos falando de 32 GB aqui), o mongo ou o Redis travam.

Eu li as seguintes perguntas anteriores sobre isso:

  1. Limitar o uso da RAM do MongoDB : aparentemente, a maioria da RAM é usada pelo cache do WiredTiger
  2. Memória limite do MongoDB : aqui, aparentemente, o problema era dados de log
  3. Limite o uso de memória RAM no MongoDB : aqui eles sugerem limitar a memória do mongo para que ele use uma quantidade menor de memória para seu cache / logs / dados
  4. MongoDB usando muita memória : aqui eles dizem que é o sistema de cache WiredTiger que tende a usar o máximo de RAM possível para fornecer acesso mais rápido. Eles também afirmamit's completely okay to limit the WiredTiger cache size, since it handles I/O operations pretty efficiently
  5. Existe alguma opção para limitar o uso da memória do mongodb? : cache novamente, eles também adicionamMongoDB uses the LRU (Least Recently Used) cache algorithm to determine which "pages" to release, you will find some more information in these two questions
  6. Relação MongoDB / RAM / índice : citação:MongoDB keeps what it can of the indexes in RAM. They'll be swaped out on an LRU basis. You'll often see documentation that suggests you should keep your "working set" in memory: if the portions of index you're actually accessing fit in memory, you'll be fine.
  7. como liberar o cache usado pelo MongoDB? : mesma resposta que em 5.

Agora, o que pareço entender de todas essas respostas é que:

  1. Para um acesso mais rápido, seria melhor para o mongo caber todos os índices na RAM. No entanto, no meu caso, estou bem com índices que residem parcialmente no disco, pois tenho um SSD bastante rápido.
  2. A RAM é usada principalmente para armazenamento em cache pelo mongo.

Considerando isso, eu esperava que o mongo tentasse usar o máximo de espaço de RAM possível, mas também poderia funcionar com pouco espaço de RAM e buscar a maioria das coisas do disco. No entanto, limitei a memória do mongo Docker container (para 8 GB, por exemplo), usando --memorye --memory-swap, mas em vez de buscar coisas no disco, o mongo travou assim que ficou sem memória.

Como forçar o mongo a usar apenas a memória disponível e a buscar do disco tudo o que não cabe na memória?

Simone Bronzini
fonte
É chamado assassino OOM. O MongoDB foi projetado para rodar em hardware comum. Eu nunca o executaria com recursos artificialmente limitados. Se você possui apenas um banco de dados pequeno, o MongoDB não é a escolha ideal. Se você possui um banco de dados grande (de três milhões a bilhões de entradas), limitar os recursos é uma má escolha. Conforme o seu problema: você não pode comer o bolo. Escolher.
Markus W Mahlberg
Se configurado corretamente, o MongoDB não deve travar quando estiver sem memória. Você pode confirmar a versão específica do servidor MongoDB e do sistema operacional que está usando e também descrever a falha com mais detalhes? Por exemplo, há alguma mensagem no log do MongoDB ou dmesgcorrelacionada com o desligamento inesperado? A possibilidade mais provável com o Docker é que os processos no contêiner detectem a RAM geral disponível em vez do limite do contêiner.
Stennie
De acordo com as Notas de produção do MongoDB : se você executar mongodem um contêiner ( lxc, cgroupsDocker, etc.) que não tenha acesso a toda a RAM disponível em um sistema, será necessário definir storage.wiredTiger.engineConfig.cacheSizeGBum valor menor que a quantidade de RAM disponível em o recipiente. A quantidade exata depende dos outros processos em execução no contêiner, mas normalmente não deve ser maior que o valor padrão de 50% da RAM menos 1 GB.
Stennie

Respostas:

9

Como por MongoDB BOL Aqui alterado na versão 3.4: Os valores podem variar de 256MBpara 10TBe pode ser um float. Além disso, o valor padrão também foi alterado.

No início 3.4, o cache interno do WiredTiger , por padrão, usará o maior de:

50% of RAM minus 1 GB, or
256 MB.

Com WiredTiger, o MongoDB utiliza o WiredTiger internal cache e o filesystem cache.

Através do filesystem cache, o MongoDB usa automaticamente toda a memória livre que não é usada pelos WiredTiger cacheou por outros processos.

O storage.wiredTiger.engineConfig.cacheSizeGB limita o tamanho do WiredTigercache interno. O sistema operacional usará a memória livre disponível para o cache do sistema de arquivos, o que permite que os arquivos de dados compactados do MongoDB permaneçam na memória. Além disso, operating systemele usará qualquer RAM livre para armazenar em buffer os blocos do sistema de arquivos e o cache do sistema de arquivos.

Para acomodar os consumidores adicionais de RAM , talvez seja necessário diminuir WiredTigero tamanho do cache interno.

Para obter mais informações sobre o mecanismo de armazenamento WiredTiger e as opções do arquivo de configuração, consulte

Md Haidar Ali Khan
fonte
4

Na verdade, se você olhar de perto, não é o mongod que morre por "falta de memória", é o gerenciador de OOM (falta de memória) do kernel que mata o mongod, porque possui o maior uso de memória.

Sim, você pode tentar resolver o problema com o parâmetro de configuração monngodb cacheSizeGB , mas no ambiente de contêiner, é melhor usar o cgroups para limitar os recursos que qualquer um dos seus três contêineres obtém.

JJussi
fonte