Merhaba arkadaşlar, bugün sizlere Linux sunucularımızda zaman zaman başımıza gelen ve can sıkıcı olabilen OOM Killer (Out-Of-Memory Killer) olayını anlatacağım. Özellikle veritabanı, web sunucusu gibi kritik servislerin aniden sonlanmasına sebep olan bu mekanizmayı nasıl anlarız ve bu kritik süreçleri nasıl koruruz, adım adım bakalım. Bu ayarları yaparak sunucunuzun daha stabil ve öngörülebilir çalışmasını sağlayabilirsiniz.
OOM Killer Nedir ve Nasıl Çalışır?
Linux kernel'i, sistem fiziksel belleği (RAM) ve takas alanı (swap) tükendiğinde panik yapmak yerine, "OOM Killer" adı verilen akıllı bir katili devreye sokar. Bu katilin görevi, sistemin kilitlenmesini önlemek için bellek tüketen süreçleri bulup sonlandırmaktır. Hangi sürecin sonlandırılacağına karar verirken bir "badness score" (kötülük puanı) hesaplar. Bu puana sürecin ne kadar bellek tükettiği, çalışma süresi, kritiklik derecesi gibi faktörler etki eder.
OOM Killer Loglarını Okuma ve Anlama
OOM Killer bir süreci öldürdüğünde, bunun kaydını kernel loglarında bırakır. Bu logları kontrol etmek ilk adımımız olmalı. Aşağıdaki komutlarla son OOM olaylarını görebilirsiniz.
Ya da daha detaylı loglar için:
Bu loglarda, hangi sürecin (PID ile), ne kadar bellek tükettiği için ve hangi skorla öldürüldüğü bilgisi yer alır. Bu bilgi, hangi servislerin risk altında olduğunu anlamamızı sağlar.
Kritik Süreçleri Koruma Yöntemleri
Şimdi gelelim asıl meseleye: Veritabanınız (MySQL/MariaDB, PostgreSQL), web sunucunuz (Nginx, Apache) veya özel bir uygulamanız OOM Killer kurbanı olmasın diye neler yapabiliriz? İşte benim sunucularımda genellikle uyguladığım yöntemler.
Yöntem 1: Süreç OOM Skorunu Manuel Ayarlama (oom_score_adj)
Her sürecin /proc/[PID]/oom_score_adj dosyasında -1000 ile +1000 arasında bir ayar değeri vardır. Bu değer, OOM skoruna eklenir.
-1000: Sürecin ASLA öldürülmeyeceği anlamına gelir.
0: Varsayılan. Kernel hesaplamasına göre hareket edilir.
+1000: Sürecin her zaman ilk öldürülecek aday olması için işaretler.
Kritik bir süreci korumak için oom_score_adj değerini negatif yapmalıyız. Örneğin, PID'si 1234 olan MySQL sürecini koruyalım:
Ancak bu ayar süreç yeniden başlatılınca sıfırlanır. Kalıcı olması için, servis başlatma script'ine (systemd service dosyasına) bu ayarı eklemeliyiz.
Yöntem 2: Systemd Servisleri İçin Kalıcı Koruma
Systemd kullanan modern dağıtımlarda (Ubuntu 16.04+, CentOS/RHEL 7+), korumak istediğiniz servisin .service dosyasına özel bir direktif ekleyebiliriz. Bu en temiz yöntemdir.
Örneğin, MariaDB servisini korumak için:
Açılan editör penceresine aşağıdaki içeriği ekleyip kaydedin:
Ardından servisi yeniden yükleyip başlatın:
Aynı yöntemi nginx.service, postgresql.service veya özel uygulamanız için de uygulayabilirsiniz. OOMScoreAdjust direktifi tam olarak bu iş için vardır.
Yöntem 3: Uygulama Başlatma Script'ine Ekleme
Systemd dışında, eski SysV init script'leri veya elle başlattığınız uygulamalar için, başlatma komutunun hemen öncesine aşağıdaki satırı ekleyebilirsiniz. Bu, sürecin başlar başlamaz koruma altına alınmasını sağlar.
Ek Tavsiyeler ve Dikkat Edilmesi Gerekenler
1. Her Şeyi -1000 Yapmayın: Tüm süreçleri korursanız, bellek gerçekten tükendiğinde OOM Killer hiçbir şey yapamaz ve sisteminiz tamamen kilitlenebilir. Sadece gerçekten vazgeçilmez olan 2-3 süreci koruyun.
2. Bellek Limitlerini Gözden Geçirin: OOM olaylarını önlemenin en iyi yolu, yeterli RAM sağlamak ve uygulamalarınızın bellek limitlerini (örn., MySQL'in innodb_buffer_pool_size'ı) fiziksel RAM'inizi aşmayacak şekilde ayarlamaktır.
3. Swap Alanını Kontrol Edin: Yeterli swap alanınız yoksa OOM durumu daha erken tetiklenir. Özellikle düşük RAM'li sunucularda swap alanını kontrol edin.
4. Monitoring Yapın: free -h, top, htop gibi araçlarla bellek kullanımınızı düzenli takip edin.
Umarım bu rehber, sunucularınızda yaşadığınız ani servis kesintilerinin önüne geçmenize yardımcı olur. Ben genellikle systemd yöntemini kullanıyorum, hem kalıcı hem de yönetmesi kolay.
Peki siz bu konfigürasyonu kendi sunucularınızda nasıl yapıyorsunuz? OOM Killer kurbanı olan başka ilginç süreçlerle karşılaştınız mı? Takıldığınız bir yer olursa aşağıya yazmaktan çekinmeyin, beraber bakalım.
Linux kernel'i, sistem fiziksel belleği (RAM) ve takas alanı (swap) tükendiğinde panik yapmak yerine, "OOM Killer" adı verilen akıllı bir katili devreye sokar. Bu katilin görevi, sistemin kilitlenmesini önlemek için bellek tüketen süreçleri bulup sonlandırmaktır. Hangi sürecin sonlandırılacağına karar verirken bir "badness score" (kötülük puanı) hesaplar. Bu puana sürecin ne kadar bellek tükettiği, çalışma süresi, kritiklik derecesi gibi faktörler etki eder.
OOM Killer bir süreci öldürdüğünde, bunun kaydını kernel loglarında bırakır. Bu logları kontrol etmek ilk adımımız olmalı. Aşağıdaki komutlarla son OOM olaylarını görebilirsiniz.
Bash:
sudo dmesg | grep -i "killed process"
Ya da daha detaylı loglar için:
Bash:
sudo grep -i "out of memory" /var/log/syslog
Bash:
sudo grep -i "killed process" /var/log/kern.log
Bu loglarda, hangi sürecin (PID ile), ne kadar bellek tükettiği için ve hangi skorla öldürüldüğü bilgisi yer alır. Bu bilgi, hangi servislerin risk altında olduğunu anlamamızı sağlar.
Şimdi gelelim asıl meseleye: Veritabanınız (MySQL/MariaDB, PostgreSQL), web sunucunuz (Nginx, Apache) veya özel bir uygulamanız OOM Killer kurbanı olmasın diye neler yapabiliriz? İşte benim sunucularımda genellikle uyguladığım yöntemler.
Her sürecin /proc/[PID]/oom_score_adj dosyasında -1000 ile +1000 arasında bir ayar değeri vardır. Bu değer, OOM skoruna eklenir.
-1000: Sürecin ASLA öldürülmeyeceği anlamına gelir.
0: Varsayılan. Kernel hesaplamasına göre hareket edilir.
+1000: Sürecin her zaman ilk öldürülecek aday olması için işaretler.
Kritik bir süreci korumak için oom_score_adj değerini negatif yapmalıyız. Örneğin, PID'si 1234 olan MySQL sürecini koruyalım:
Bash:
echo -1000 | sudo tee /proc/1234/oom_score_adj
Ancak bu ayar süreç yeniden başlatılınca sıfırlanır. Kalıcı olması için, servis başlatma script'ine (systemd service dosyasına) bu ayarı eklemeliyiz.
Systemd kullanan modern dağıtımlarda (Ubuntu 16.04+, CentOS/RHEL 7+), korumak istediğiniz servisin .service dosyasına özel bir direktif ekleyebiliriz. Bu en temiz yöntemdir.
Örneğin, MariaDB servisini korumak için:
Bash:
sudo systemctl edit mariadb.service
Açılan editör penceresine aşağıdaki içeriği ekleyip kaydedin:
INI:
[Service]
OOMScoreAdjust=-1000
Ardından servisi yeniden yükleyip başlatın:
Bash:
sudo systemctl daemon-reload
sudo systemctl restart mariadb.service
Aynı yöntemi nginx.service, postgresql.service veya özel uygulamanız için de uygulayabilirsiniz. OOMScoreAdjust direktifi tam olarak bu iş için vardır.
Systemd dışında, eski SysV init script'leri veya elle başlattığınız uygulamalar için, başlatma komutunun hemen öncesine aşağıdaki satırı ekleyebilirsiniz. Bu, sürecin başlar başlamaz koruma altına alınmasını sağlar.
Bash:
#!/bin/bash
echo -1000 > /proc/self/oom_score_adj
# Asıl uygulama başlatma komutu buraya gelir (ör: /usr/bin/my_critical_app)
exec /usr/bin/my_critical_app
1. Her Şeyi -1000 Yapmayın: Tüm süreçleri korursanız, bellek gerçekten tükendiğinde OOM Killer hiçbir şey yapamaz ve sisteminiz tamamen kilitlenebilir. Sadece gerçekten vazgeçilmez olan 2-3 süreci koruyun.
2. Bellek Limitlerini Gözden Geçirin: OOM olaylarını önlemenin en iyi yolu, yeterli RAM sağlamak ve uygulamalarınızın bellek limitlerini (örn., MySQL'in innodb_buffer_pool_size'ı) fiziksel RAM'inizi aşmayacak şekilde ayarlamaktır.
3. Swap Alanını Kontrol Edin: Yeterli swap alanınız yoksa OOM durumu daha erken tetiklenir. Özellikle düşük RAM'li sunucularda swap alanını kontrol edin.
4. Monitoring Yapın: free -h, top, htop gibi araçlarla bellek kullanımınızı düzenli takip edin.
Umarım bu rehber, sunucularınızda yaşadığınız ani servis kesintilerinin önüne geçmenize yardımcı olur. Ben genellikle systemd yöntemini kullanıyorum, hem kalıcı hem de yönetmesi kolay.
Peki siz bu konfigürasyonu kendi sunucularınızda nasıl yapıyorsunuz? OOM Killer kurbanı olan başka ilginç süreçlerle karşılaştınız mı? Takıldığınız bir yer olursa aşağıya yazmaktan çekinmeyin, beraber bakalım.