Linux OOM Killer Tuning pentru VPS: un ghid practic

12 min citire - 8 iunie 2026

hero section cover
Cuprins
  • Reglarea Linux OOM killer pentru VPS
  • Cum alege OOM killer o victimă
  • Identificarea presiunii asupra memoriei înainte de blocare
  • Protejarea proceselor critice cu oom_score_adj
  • Limitarea memoriei cu cgroups și systemd
  • Citirea jurnalelor după un eveniment OOM
  • Concluzii
Distribuie

Reglați Linux OOM killer pe VPS-ul dvs. pentru a proteja bazele de date și SSH, pentru a limita procesele fugare cu cgroups și pentru a împiedica uciderea serviciului greșit.

Reglarea Linux OOM killer pentru VPS

Linux OOM killer este ultima soluție a kernel-ului atunci când memoria se epuizează: acesta alege un proces și îl termină pentru a menține sistemul în funcțiune. Pe un VPS, unde memoria RAM este limitată și nu există nicio soluție de rezervă, alegerea implicită este adesea cea greșită. Baza dvs. de date este oprită, un proces de lungă durată supraviețuiește, iar dvs. rămâneți să vă dați seama de ce. Acest ghid acoperă modul în care OOM killer evaluează procesele, cum să orientați această evaluare către serviciile dvs. critice și cum să utilizați cgroups astfel încât un singur proces scăpat de sub control să nu poată trage restul sistemului după el.


 

Cum alege OOM killer o victimă

Când kernelul nu poate recupera suficientă memorie prin eliminarea din cache-ul de pagini sau prin swap, acesta invocă OOM killer. Fiecare proces are un oom_score un scor între 0 și 1000, derivat în principal din Resident Set Size (RSS) și utilizarea swap-ului. Procesul cu cel mai mare scor primește un SIGKILL.

RSS domină calculul, motiv pentru care uciderea se îndreaptă aproape întotdeauna către cel mai mare consumator de memorie. Acesta este adesea baza de date, serverul de aplicații sau orice proces de lungă durată care efectuează cea mai utilă muncă. Procesul care a declanșat de fapt alocarea, „invoker”, este rareori cel care este terminat.

Există două tipuri de evenimente OOM pe care trebuie să le diferențiați:

  • OOM global: gazda (sau VPS-ul dvs. în ansamblu) nu mai are RAM și swap. Kernelul scanează fiecare proces și îl oprește pe cel cu cel mai mare scor.
  • OOM cgroup: un anumit cgroup a atins limita de memorie. Kernelul termină doar procesele din acel cgroup, chiar dacă restul sistemului are memorie disponibilă.

Dacă ați configurat limitele unităților systemd sau rulați containere, majoritatea evenimentelor OOM vor fi OOM-uri cgroup. Acesta este un lucru bun: raza de acțiune este limitată.

Identificarea presiunii asupra memoriei înainte de blocare

Evenimentele OOM nu sunt aproape niciodată bruște. De obicei, există mai întâi o perioadă de creștere a presiunii, iar scopul monitorizării este de a o detecta în acea perioadă.

free -h vă oferă o imagine de ansamblu a sistemului. Coloana care contează este available, nu free: aceasta reprezintă cache-ul de pagini recuperabil și reflectă ceea ce puteți aloca efectiv fără a recurge la swap. Mențineți MemAvailable aproximativ 10-15% MemTotal la încărcare maximă.

Pentru atribuirea pe proces, sortați după RSS:

ps aux --sort=-%mem | head -10

Sau utilizați htop și sortați după RES. Valorile pe care le vedeți aici sunt introduse direct în scorul kernelului, astfel încât intrările de sus sunt cele mai probabile ținte OOM.

Pe kernel-urile 4.20 și mai noi, Pressure Stall Information este sistemul de avertizare timpurie care merită integrat în monitorizare:

cat /proc/pressure/memory

Cifra some avg10 figura reprezintă procentul de timp în care cel puțin o sarcină a fost blocată așteptând memorie în ultimele zece secunde. Sub 5% este în regulă. Valorile susținute peste 10% înseamnă că sistemul își petrece timp real blocat în recuperarea memoriei, iar o oprire din cauza OOM este plauzibilă.

Swap thrashing apare în vmstat 1 ca valori diferite de zero si și so care se mențin în timp. O cantitate mică de swap rezident este inofensivă. Swap-in și swap-out constante nu sunt.

Protejarea proceselor critice cu oom_score_adj

Scorul calculat de kernel poate fi ajustat pentru fiecare proces prin oom_score_adj, pe o scară de la -1000 (imun) la +1000 (ucide-mă primul). Ajustarea este adăugată direct la scorul final.

Pentru o modificare punctuală a unui proces în execuție:

echo -500 | sudo tee /proc/$(pidof sshd)/oom_score_adj

Pentru orice doriți să persiste la reporniri, setați-l în unitatea systemd. Acesta este locul potrivit pentru sshd, baza dvs. de date și orice altceva pe care nu vă puteți permite să-l pierdeți:

[Service]
OOMScoreAdjust=-900

Valori implicite sensibile de la care să pornești:

  • sshd: -1000. Dacă pierzi accesul la distanță în timpul unei crize de memorie, recuperarea devine mult mai dificilă.
  • MySQL, PostgreSQL, Redis: -800 până la -900. Protecție puternică fără a le face complet de neatins într-o situație cu adevărat catastrofală.
  • Procesele de lucru ale aplicațiilor, sarcinile batch, sarcinile cron: +100 până la +500. Acestea sunt procesele pe care ați prefera să le vedeți oprite decât baza de date.

Nu setați totul la -1000. Dacă nimic nu poate fi oprit, kernelul va intra în panică sau se va bloca, ceea ce este și mai rău.

Limitarea memoriei cu cgroups și systemd

Ajustarea scorurilor influențează cine este oprit. Cgroups influențează dacă oprirea globală are loc vreodată. Prin atribuirea unei limite superioare fixe fiecărui serviciu, direcționați eșecurile de memorie într-un singur cgroup, în loc să lăsați un singur proces să epuizeze întregul VPS.

Într-un fișier de unitate systemd:

[Service]
MemoryHigh=400M
MemoryMax=512M
OOMPolicy=stop
Restart=on-failure
RestartSec=5s

MemoryHigh este o limitare flexibilă: kernelul recuperează agresiv pagini din cgroup deasupra acestui punct, dar nu oprește nimic. MemoryMax este limita maximă strictă. Dacă cgroup încearcă să aloce memorie peste această limită, kernelul oprește un proces din interiorul cgroup. Cu Restart=on-failure serviciul revine imediat.

Pe cgroup v2 (Ubuntu 22.04 și versiuni ulterioare, Debian recent, RHEL 9), memory.oom.group se opresc toate procesele din cgroup împreună, în loc să se lase procese orfane în urmă. Este util pentru serviciile cu mai multe procese, cum ar fi grupurile PHP-FPM, unde un grup oprit parțial va funcționa incorect.

Câteva note specifice aplicației care merită aplicate:

  • PHP-FPM: setați pm = ondemand pe instanțe VPS mici și dimensiunea pm.max_children în funcție de RSS mediu pe lucrător, nu de valoarea implicită. Un pool dimensionat pentru 4 GB de spațiu liber pe un VPS de 2 GB va genera o eroare OOM la prima umplere.
  • Node.js: limitați heap-ul V8 cu --max-old-space-size=512 (în MB). Fără aceasta, Node va crește fără probleme până când va interveni kernelul.
  • MySQL și PostgreSQL: innodb_buffer_pool_size și shared_buffers ar trebui să lase spațiu liber pentru cache-ul de pagini al sistemului de operare, memoria de conexiune și orice alți utilizatori de pe server. Valorile implicite presupun un server dedicat.

Citirea jurnalelor după un eveniment OOM

Când se declanșează OOM killer, kernelul descarcă un raport detaliat în bufferul inelar. Extrageți-l cu:

dmesg -T | grep -iE 'killed process|out of memory'
journalctl -k --grep='Out of memory'

Blocul care trebuie citit cu atenție începe cu invocatorul și se termină cu victima. Kernelul afișează o listă completă a sarcinilor cu RSS-ul fiecărui proces, utilizarea swap-ului și oom_score_adj. Merită verificate trei lucruri:

  • Constrângerea. CONSTRAINT_NONE înseamnă un OOM global, CONSTRAINT_MEMCG înseamnă că un cgroup a atins limita. Soluția este diferită în fiecare caz.
  • Free swap. Dacă aceasta este 0kB, atât RAM-ul, cât și swap-ul au fost epuizate. Fie adăugați swap, măriți MemoryMax pe procesul vinovat sau reduceți concurența.
  • Scorul victimei comparativ cu toate celelalte. Dacă scorul victimei nu este mult mai mare decât al următoarelor câteva procese, oom_score_adj valori nu fac suficientă treabă. Măriți diferența.

În mod specific pentru OOM-urile cgroup, contorul de kill se află memory.events în interiorul cgroup-ului:

cat /sys/fs/cgroup/system.slice/mysql.service/memory.events

O creștere a oom_kill înseamnă că serviciul își atinge în mod repetat limita. Acesta este un semnal pentru a crește MemoryMax, a analiza profilul sarcinii de lucru sau a muta serviciul pe un plan mai mare, nu a continua să-l reporniți în buclă.

Concluzii

Reglarea OOM killer nu înseamnă a-l elimina. Înseamnă a controla care proces plătește prețul atunci când memoria se epuizează și a reduce aria de impact atunci când se întâmplă acest lucru. Modelul care se menține în producție:

  • Protejați serviciile pe care nu vă puteți permite să le pierdeți, în special sshd și bazele de date.
  • Limitați tot restul cu MemoryMax într-o unitate systemd, astfel încât o singură fugă să însemne o singură repornire, nu o întrerupere.
  • Monitorizați PSI și MemAvailable în loc să aștepți ca dmesg să vă spună ce s-a întâmplat după aceea.
  • Lăsați 15-20% din RAM ca rezervă. Optimizarea nu poate compensa un VPS care este pur și simplu prea mic pentru volumul de lucru.

Dacă presiunea asupra memoriei este structurală, mai degrabă decât configurabilă, aveți nevoie de mai multă memorie RAM sau de un spațiu de stocare mai rapid, susținut de swap. Planurile VPS ale FDC Servers rulează pe AMD EPYC cu stocare NVMe, ceea ce menține citirile susținute de swap suficient de rapide încât scurtele explozii de memorie să nu degenereze în opriri.

Blog

În prim plan săptămâna aceasta

Mai multe articole
Linux OOM Killer Tuning pentru VPS: un ghid practic

Linux OOM Killer Tuning pentru VPS: un ghid practic

Reglați Linux OOM killer pe VPS-ul dvs. pentru a proteja bazele de date și SSH, pentru a limita procesele fugare cu cgroups și pentru a împiedica uciderea serviciului greșit.

12 min citire - 8 iunie 2026

Linux Traffic Control (tc): un ghid practic

12 min citire - 5 iunie 2026

Mai multe articole
background image

Aveți întrebări sau aveți nevoie de o soluție personalizată?

icon

Opțiuni flexibile

icon

Acoperire globală

icon

Implementare instantanee

icon

Opțiuni flexibile

icon

Acoperire globală

icon

Implementare instantanee