È successo due volte nell’ultima settimana al server di questo sito ed è successo a molti Linux ospitati su macchine virtuali: improvvisamente sembra che un task occupi tutta la memoria disponibile, Linux va in out of memory e l’azione più rapida per ripristinare i servizi è un reboot.
Questa volta tutto è cominciato da qui:
Sep 15 17:16:26 mx kernel: httpd invoked oom-killer: gfp_mask=0x280da, order=0, oom_adj=0, oom_score_adj=0
Sep 15 17:16:26 mx kernel: httpd cpuset=/ mems_allowed=0
Sep 15 17:16:26 mx kernel: Pid: 25761, comm: httpd Not tainted 2.6.32-279.5.2.el6.centos.plus.x86_64 #1
oom (out of memory) killer entra in azione quando la memoria di sistema (fisica + swap) viene esaurita; il suo compito è quello di far fuori dei processi per liberare memoria e ristabilire la normalità.
Se entra inazione oom-killer vuol dire che bisogna fare qualcosa per evitare che la memoria si esaurisca.
Il problema risiede nell’approccio ottimista di allocazione della memoria di Linux, l’overcommit, un mix di overbooking delle compagnie aeree e di speranza che i processi non richiedano una quantità esagerata di memoria.
Ma il peggio può accadere. Sempre.
La maggior parte delle distribuzioni impostano /proc/sys/vm/overcommit_memory
a zero, che equivale a dire al kernel di utilizzare il vecchio algoritmo euristico di overcommit, che può portare ai problemi descritti sopra.
L’errore peggiore che si possa fare è di impostare /proc/sys/vm/overcommit_memory
a 1, in quanto qualsiasi chiamata a malloc() andrà a buon fine, peggiorando la situazione.
Se si usa un kernel 2.6 o superiore, la soluzione migliore è impostare /proc/sys/vm/overcommit_memory
a 2; in questo modo la quantità massima di memoria allocabile è data dalla formula
SWAP + RAM * (OR / 100)
Dove SWAP e RAM sono rispettivamente la dimensione dell’area di swap e della RAM, mentre OR è il valore impostato in /proc/sys/vm/overcommit_ratio
La percentuale dipende dall’esperienza e dalla casistica: alcuni consigliano 50 altri 80.
Per impostare i parametri del kernel in una CentOS o similare, includere queste due righe nel file /etc/sysctl.conf
vm.overcommit_memory = 2
vm.overcommit_ratio = 80
e riavviare il sistema.
Riferimenti:
Lascia un commento