4546 Views
Tempo de leitura: 4 MinutosO OOM Killer é um recurso do Linux Kernel que, em situações de sobrecarga de memória, é chamado pelo Kernel para finalizar serviços que demandem maior consumo do recurso. É tipo um carrasco.
Ele possui um conceito chamado Heurística de Maldade que, a partir de determinadas regras, calcula a maldade de um PID quanto ao consumo de memória.
Sabemos que cada PID representa parte ou a totalidade de um serviço em execução no sistema, mas para o OOM Killer tudo é PID. Não existe serviço importante. Se é ofensor, pode ser morto.
O OOM incrementa uma pontuação para cada PID durante o tempo de vida desses PIDs. Essa pontuação vai de 0 à 1000.
Se um PID consumir toda memória permitida à ele, a pontuação dele será 1000. Se consumir metade da memória permitida, será 500.
O fato de um serviço chegar ao limite de memória permitida não é determinante para o seu encerramento através do OOM Killer, mas se faltar memória para o sistema com certeza será.
Quando o OOM-Killer entra em ação?
Em determinadas situações, principalmente quando ocorrem sobrecargas no consumo de memória, o OOM Killer detecta os PIDs com maiores pontuação e senta o aço. Sem dó. Pode ser um Webserver, Banco de Dados, etc, seja o que for, vai ser encerrado.
Contudo, é possível impedir que determinados PIDs sejam finalizados pelo OOM decrementando a pontuação dos PIDs desse serviço, mantendo a Heurística de Maldade com valor negativo para esses PIDs ou no máximo zerada.
Problemas que o OOM Killer pode causar
Dentro das regras de negócios, determinados serviços são cruciais para o Core Business das empresas, e é muito importante garantir que esses serviços estejam sempre no ar.
Um banco de dados como o MySQL ou PostgreSQL que esteja transacionando dados e que seja subitamente encerrado pelo OOM Killer pode ter tabelas corrompidas. Alguns engines como o InnoDB do MySQL possuem recursos para recuperação automática, mas esse não é o tipo de coisa que você deseja precisar.
Além do básico, que é otimizar serviços importantes e o próprio sistema operacional com tunings e hardenings a fim de evitar sobrecargas, é preciso, decrementar a pontuação desses serviços para garantir que o OOM Killer os desconsidere.
Evitando que o OOM Killer encerre serviços
Enrolei, mas aqui está. Veremos a seguir como evitar que o OOM Killer finalize serviços importantes.
Primeiro, saibamos que todo PID possui um arquivo como este:
cat /proc/1234/oom_score_adj 678
Para definir que esse PID esteja fora do OOM-Killer, basta setar um valor entre -1000 e 1000. Pode-se fazer isso da seguinte forma:
echo -1000 > /proc/1234/oom_score_adj
Ao setar -1000, mesmo que o PID consuma todo o limite de memória permitida à ele, o que o deixaria com valor 1000 na Heurística de Maldade uma vez que o OOM-Killer continuará incrementando sua pontuação, o valor máximo de pontuação que esse PID chegará será 0 (Zero).
Automatizando a retirada de serviços do OOM-Killer
Observe que aplicar -1000 para um PID não o faz completamente excluído do OOM-Killer, pois a pontuação desse PID pode chegar a zero. O OOM-Killer encontrará outros PIDs para matar, mas se seu serviço for o real ofensor do sistema e a sobrecarga persistir, uma hora ou outra, sob certas circunstâncias, o OOM-Killer poderá finalizar seu serviço.
Para evitar que isso ocorra é importante manter o valor -1000 no(s) PID(s) que se deseja deixar fora do OOM. Para isso um Cronjob rodando de tempos em tempos reaplicando o valor -1000 é uma boa solução.
Para isso seria preciso:
-
01 – Identificar todos PIDs necessários;
02 – Colocá-los em um looping com
for
ou while
;03 – Schedular no Crontab.
Vejamos passo a passo:
01 – Identificar todos PIDs necessários:
Alguns serviços possuem somente 1 PID. Outros são compostos por diversos PIDs. Sabemos que precisamos aplicar valor -1000 para cada PID que compõe o serviço, sendo um ou vários.
Vamos obter o PID com pgrep
pgrep mysql 12345
Agora com ps aux
:
ps aux | grep mysql | grep -v grep | awk '{print$2}' 759 1567 1568
Veja qual o atende mais apropriadamente e o utilize.
02 – Colocar em um looping;
Usando o comando acima, podemos fazer laços com for
ou while
como nos exemplos destacados a seguir:
Usando for
:
for PID in $(pgrep mysql); do echo -1000 > /proc/${PID}/oom_score_adj; done
Usando while
:
pgrep mysql | while read PID; do echo -1000 > /proc/${PID}/oom_score_adj; done
03 – Schedular no Crontab
Com posse de um single-line funcional como esses laços, basta schedular um job no Crontab. Aqui no Blog há um artigo bem legal sobre Crontab. Segue o link:
https://www.blogporta80.com.br/2014/12/28/artigos-trabalhando-com-crontab-2
Considerações finais
Não entenda o OOM-Killer como um vilão. Muito pelo contrário, ele é um aliado do sistema operacional Linux. O fato de ele entrar em ação nos mostra que nossos ambientes estão com algum tipo de problema, e que precisamos intervir para diagnosticar e resolver na raiz.
Retirar serviços importantes do OOM-Killer é uma boa prática, com toda certeza, mas entender por que o sistema está sobrecarregando é fundamental
Espero ter ajudado de alguma forma. E se chegou até aqui, curte o post, um abraço e até a próxima.