Evite o desmembramento do aplicativo de falta de memória do Linux

34

Estou descobrindo que, ocasionalmente, minha caixa do Linux fica sem memória e começa a destruir processos aleatórios para lidar com isso.

Estou curioso para saber o que os administradores fazem para evitar isso. É a única solução real para aumentar a quantidade de memória (apenas aumentar a troca ajudará?) Ou existem maneiras melhores de configurar a caixa com o software para evitar isso? (ou seja, cotas ou algo assim?).

Eddie Parker
fonte
Eu encontrei uma resposta aqui: serverfault.com/questions/362589/... resposta Patrick é muito instrutivo
Amaury

Respostas:

44

Por padrão, o Linux tem um conceito um tanto danificado de gerenciamento de memória: ele permite que você aloque mais memória do que o seu sistema e, em seguida, dispara aleatoriamente um processo na cabeça quando há problemas. (A semântica real do que é morto é mais complexa do que isso - o Google "Linux OOM Killer" para muitos detalhes e argumentos sobre se é uma coisa boa ou ruim).


Para restaurar alguma aparência de sanidade ao seu gerenciamento de memória:

  1. Desativar o OOM Killer (Coloque vm.oom-kill = 0em /etc/sysctl.conf)
  2. Desativar overcommit de memória (Coloque vm.overcommit_memory = 2em /etc/sysctl.conf)
    Observe que este é um valor trinário: 0 = "calcule se temos RAM suficiente", 1 = "Sempre diga sim", 2 = "diga não se não tivermos tem a memória ")

Essas configurações farão o Linux se comportar da maneira tradicional (se um processo solicitar mais memória do que o disponível malloc () falhará e o processo que solicita a memória deve lidar com essa falha).

Reinicie sua máquina para recarregá-la /etc/sysctl.confou use o procsistema de arquivos para ativar imediatamente, sem reiniciar:

echo 2 > /proc/sys/vm/overcommit_memory 
voretaq7
fonte
11
Não é o Linux que está prejudicado, mas os programadores que alocam a memória, nunca a usam. As VMs Java são notórias com isso. Eu, como administrador que gerencia servidores executando aplicativos Java, não sobreviveria um segundo sem comprometer demais.
Aleksandar Ivanisevic
11
Programadores Java não alocam memória não utilizada, não há malloc em java. Eu acho que você está confundindo isso com configurações da JVM como -Xms. De qualquer forma, aumentar o tamanho da memória virtual adicionando espaço de troca é uma solução muito mais segura do que exagerar.
Jlliagre
5
Observe que esta solução não impedirá que o sistema fique sem memória ou acabe com os processos. Ele apenas reverterá o comportamento tradicional do Unix, onde, se um processo consumir toda a sua memória, o próximo que tentar fazer malloc não terá nenhum (e provavelmente travará). Se você não tiver sorte, o próximo processo é o init (ou algo mais crítico), o que o OOM Killer geralmente evita.
pehrs 14/05/10
8
jlliagre, eu disse Java VMs (máquinas virtuais), e não programas Java, embora a partir de uma perspectiva de administração é a mesma :)
Aleksandar Ivanisevic
8
Talvez valha a pena mencionar aqui que a adição do acima acima /etc/sysctl.confprovavelmente só terá efeito na próxima reinicialização; se você quiser fazer alterações agora, você deve usar o sysctlcomando com permissões de root, por exemplo:sudo sysctl vm.overcommit_memory=2
nickgrim
3

A resposta curta, para um servidor, é comprar e instalar mais RAM.

Um servidor que rotineiramente experimentou erros de OOM ( falta de memória) e, além da opção de sysctl de confirmação excessiva do gerente de VM (memória virtual) nos kernels do Linux, isso não é uma coisa boa.

Aumentar a quantidade de swap (memória virtual que foi paginada em disco pelo gerenciador de memória do kernel) ajudará se os valores atuais forem baixos e o uso envolver muitas tarefas, com uma quantidade tão grande de memória, em vez de uma ou poucas processa cada um solicitando uma quantidade enorme da memória virtual total disponível (RAM + troca).

Para muitos aplicativos que alocam mais de duas vezes (2x), a quantidade de RAM como troca fornece um retorno menor sobre a melhoria. Em algumas simulações computacionais grandes, isso pode ser aceitável se a desaceleração da velocidade for suportável.

Com a RAM (ECC ou não), é bastante acessível para quantidades modestas, por exemplo, de 4 a 16 GB, devo admitir que não tenho esse problema há muito tempo.

O básico para analisar o consumo de memória, incluindo o uso freee top, classificado por uso de memória, como as duas avaliações rápidas mais comuns dos padrões de uso de memória. Portanto, não deixe de entender o significado de cada campo na saída desses comandos.

Sem especificações específicas de aplicativos (por exemplo, banco de dados, servidor de serviço de rede, processamento de vídeo em tempo real) e o uso do servidor (poucos usuários avançados, 100-1000s de conexões usuário / cliente), não consigo pensar em nenhuma recomendação geral sobre como lidar com o problema OOM.

mctylr
fonte
3

Aumentar a quantidade de memória física pode não ser uma resposta eficaz em todas as circunstâncias.

Uma maneira de verificar isso é o comando 'atop'. Particularmente essas duas linhas.

Este servidor está fora quando estava íntegro:

MEM | tot   23.7G | free   10.0G | cache   3.9G | buff  185.4M | slab  207.8M |
SWP | tot    5.7G | free    5.7G |              | vmcom  28.1G | vmlim  27.0G |

Quando estava funcionando mal (e antes de ajustarmos a overcommit_memory de 50 para 90, veríamos o comportamento com a vmcom executando bem acima de 50G, oom-killer explodindo processos a cada poucos segundos e a carga continuava saltando radicalmente devido aos processos filhos do NFSd serem explodidos criado e recriado continuamente.

Recentemente, duplicamos os casos em que os servidores de terminal Linux para vários usuários comprometem demais a alocação de memória virtual, mas poucas páginas solicitadas são realmente consumidas.

Embora não seja aconselhável seguir essa rota exata, ajustamos a memória de confirmação excessiva do padrão de 50 para 90, o que aliviou alguns dos problemas. Acabamos tendo que mover todos os usuários para outro servidor de terminal e reiniciar para ver todos os benefícios.

Magalhães
fonte
2

Você pode usar o ulimit para reduzir a quantidade de memória que um processo pode reivindicar antes de ser morto. É muito útil se o seu problema for um ou alguns processos de fuga que travam o servidor.

Se o seu problema é que você simplesmente não tem memória suficiente para executar os serviços necessários, existem apenas três soluções:

  1. Reduza a memória usada por seus serviços limitando caches e similares

  2. Crie uma área de troca maior. Vai custar-lhe desempenho, mas pode ganhar algum tempo.

  3. Compre mais memória

pehrs
fonte
0

Eu tive um problema semelhante relacionado a esse bug e a solução foi usar o kernel mais antigo / mais recente (corrigido).

No entanto, no momento em que eu não conseguia reiniciar minha máquina, algum tipo de solução alternativa feia era fazer login como root e limpar os caches do sistema com este comando:

echo 3 > /proc/sys/vm/drop_caches
Krzysztof Dryja
fonte
-5

@ voretaq7 linux não possui um conceito de gerenciamento de memória com dano cerebral, por padrão vm.overcommit_ratio é 0,

0       -   Heuristic overcommit handling. Obvious overcommits of
            address space are refused. Used for a typical system. It
            ensures a seriously wild allocation fails while allowing
            overcommit to reduce swap usage.  root is allowed to
            allocate slightly more memory in this mode. This is the
            default.

Dessa forma, se você tiver 4 GB de RAM e tentar alocar 4,2 GB com malloc de memória virtual, sua alocação falhará.

Com vm.overcommit_ratio = 1

            1    -   Always overcommit. Appropriate for some scientific
            applications. Classic example is code using sparse arrays
            and just relying on the virtual memory consisting almost
            entirely of zero pages.

Com vm.overcommit_ratio = 2

           2    -   Don't overcommit. The total address space commit
            for the system is not permitted to exceed swap + a
            configurable percentage (default is 50) of physical RAM.
            Depending on the percentage you use, in most situations
            this means a process will not be killed while accessing
            pages but will receive errors on memory allocation as
            appropriate.

            Useful for applications that want to guarantee their
            memory allocations will be available in the future
            without having to initialize every page.

Portanto, por padrão, o linux não compromete demais, se seu aplicativo tiver mais memória do que você tem, talvez seu código esteja com erros

c4f4t0r
fonte
2
Você se contradiz aqui. Na parte superior, você diz "por padrão, vm.overcommit_ratio é 0" e, na parte inferior, você diz "por padrão, o linux não confirma demais". Se o último fosse verdadeiro, vm.overcommit_ratio seria 2 por padrão!
Michael Hampton
vm.overcommit_ratio = 0, malloc não aloca mais memória do que sua ram física, então para mim isso significa não
confirmar demais
2
Sim, você entendeu errado.
Michael Hampton
você entendeu mal, o padrão 0, não aloca para alocar mais memória virtual do que a RAM e 2 não passar por cima de permitir espaço vm.overcommit_ratio + swap, por isso, se eu mal me dizer o que
c4f4t0r
2
Claro. "Compromissos óbvios" são recusados. O resto passa. Você precisa ler com mais atenção.
Michael Hampton