Üretimde “OOM oldu, proses öldü” cümlesi bir sonuçtur; asıl problem genelde OOM’dan önce başlayan memory pressure’dır. Yanlış refleksle (örn. “swap aç, drop_caches bas”) günü kurtarırsın ama aynı incident farklı formda tekrar eder.
Bu yazı; Linux’ta Cgroup v2 + PSI (Pressure Stall Information) + systemd-oomd üçlüsüyle, bellek baskısını erken yakalayıp kontrollü şekilde tahliye eden saha odaklı bir runbook sunar.
Neyi çözmeye çalışıyoruz?
Hedef şu üç problemi aynı anda azaltmak:
- Kernel OOM killer’ın rastgeleliği: En kötü anda en kritik prosesin gitmesi.
- Zincirleme çöküş: Memory pressure → latency artışı → retry fırtınası → daha fazla bellek.
- Operasyonel körlük: “Neden oldu?” sorusuna kanıt yerine sezgiyle cevap vermek.
Ön koşullar (kontrol listesi)
- Kernel ve dağıtım Cgroup v2 ile çalışıyor olmalı.
- systemd sürümü systemd-oomd içeriyor olmalı (çoğu modern distro’da var).
- PSI metrikleri okunabiliyor olmalı.
Hızlı doğrulama:
# cgroup v2 mi?
stat -fc %T /sys/fs/cgroup
# PSI dosyaları var mı?
ls /proc/pressure/
# oomd çalışıyor mu?
systemctl status systemd-oomd
Beklenen:
cgroup2fs/proc/pressure/memorymevcutsystemd-oomdaktif
PSI (Pressure) neyi anlatır?
PSI, “bellek yetersizliği yüzünden CPU’nun beklediği süre”yi ölçer. Bu, OOM’dan dakikalar önce sinyal üretir.
Örnek okuma:
cat /proc/pressure/memory
Saha yorumu:
someyükseliyorsa: bazı işler bekliyor → latency artışı başlar.fullyükseliyorsa: sistemin önemli kısmı bloke → incident artık görünür olur.
Tasarım: önce “hangi servis gidecek?” sorusu
OOM anında “hangi proses öldürülsün?” sorusunun cevabı, mimari kararın parçasıdır.
Pratik sınıflandırma:
- Tier-0 (kritik): kontrol düzlemi, kimlik, veri katmanı (mümkünse ölmez)
- Tier-1: API/uygulama worker’ları (ölür ama yeniden gelir)
- Tier-2: batch, rapor, cache warmer (ilk gidecekler)
Uygulama: systemd-oomd ile kontrollü tahliye
systemd, servisleri slice’lar altında yönetirken oomd’ye “bu grupta baskı yüksekse öldür” şeklinde politika verebilir.
Örnek yaklaşım (servis bazlı değil, slice bazlı yönetim):
- Uygulama iş yüklerini ayrı slice altında topla (ör.
apps.slice) - Batch işleri daha düşük öncelikli ayrı slice’a koy (ör.
batch.slice) - OOM policy’yi slice üzerinde etkinleştir
Slice için override örneği:
sudo systemctl edit apps.slice
[Slice]
ManagedOOMMemoryPressure=kill
ManagedOOMMemoryPressureLimit=60%
Benzer şekilde batch için daha agresif bir limit tanımlayabilirsin.
Runbook: Incident anında adım adım
1) Triage (5 dakika)
uptime
free -m
vmstat 1 5
cat /proc/pressure/memory
journalctl -u systemd-oomd --since "-30m" --no-pager
dmesg -T | tail -n 80
Okuma biçimi:
- PSI yükseliyor + reclaim yoğun → “baskı” var
- OOM kill logları → artık geç kalındı, root-cause ve containment’e geç
2) Containment (kontrollü alan açma)
Güvenli ilk hamleler:
- En çok bellek tüketen batch işleri durdur/ölçekle
- Cache warmup/rapor gibi “nice-to-have” süreçleri kes
- Uygulama worker’larını kontrollü azalt (traffic + retry etkisini izle)
Hızlı görünürlük:
ps -eo pid,ppid,cmd,rss --sort=-rss | head -n 20
systemd-cgtop -m
3) Doğrulama (10 dakika)
PSI düşüyor mu?
watch -n 2 'cat /proc/pressure/memory; echo; free -m'
Eğer PSI düşmüyor ama bellek artıyorsa:
- memory leak olasılığı
- retry fırtınası (kuyruk/backpressure eksik)
- kernel slab / page cache baskısı
4) Geri dönüş standardı
İyileşme sonrası:
- Geçici ölçek düşüşlerini geri al
- OOMD kill loglarını incident kanıt setine ekle
- “Neden oldu?” için metrik/trace/log korelasyonu çıkar
Test (üretime çıkmadan önce)
Lab/Stage üzerinde basit bir baskı testi:
sudo apt-get install -y stress-ng || true
stress-ng --vm 2 --vm-bytes 80% --timeout 60s
Beklenen:
- PSI yükselir
- OOMD, hedef slice içinde kontrollü kill uygular
- Kritik servisler (tier-0) korunur
Postmortem: kalıcı iyileştirme listesi
- Sınırlar: servis başına bellek limit/requests, cache boyutu
- Gözlem: PSI alarmları, reclaim/pgfault göstergeleri, oomd karar logları
- Dayanıklılık: queue/backpressure, retry bütçesi, circuit breaker
- Operasyon: “hangi servis önce gider?” kararının yazılı standardı
Sonuç
systemd-oomd, OOM’un rastgeleliğini azaltıp memory pressure’ı kontrollü tahliyeye çevirir. Değer, tool kurulumundan çok; servis önceliği, cgroup sınırları ve PSI tabanlı erken uyarı disiplininin birlikte çalışmasında ortaya çıkar.