- Aşırı değiştirmeden dolayı yanıt vermeyen veya aşırı halsiz hale gelen bir Linux sisteminin kontrolünü yeniden kazanmanın en hızlı yolu nedir?
Yukarıda Alt-SysRq-F ile daha önce yanıtlanmış
- Bu tür bir takasın ilk etapta meydana gelmesini önlemenin etkili bir yolu var mı, örneğin bir işlemin ayırmaya çalışmasına izin verilen bellek miktarını sınırlayarak?
Bu 2. bölüme cevap veriyorum. Evet, ulimit
hala tek bir işlemi sınırlayacak kadar iyi çalışıyor. Yapabilirsin:
- muhtemelen kontrolden çıkacağını bildiğiniz bir işlem için yumuşak bir sınır belirleyin
- ekstra sigorta istiyorsanız tüm süreçler için kesin bir limit belirleyin
Ayrıca, kısaca belirtildiği gibi:
Kaynak kullanımını sınırlamak ve bu tür sorunları önlemek için CGroup'ları kullanabilirsiniz
Gerçekten de, cgroups daha gelişmiş kontrol sunuyor, ancak şu anda yapılandırmak daha karmaşık.
Eski okul ulimit
Bir kez kapalı
Heres basit bir örnek:
$ bash
$ ulimit -S -v $((1*2**20))
$ r2(){r2 $@$@;};r2 r2
bash: xmalloc: .././subst.c:3550: cannot allocate 134217729 bytes (946343936 bytes allocated)
O:
- 1 GB'lık genel bellek kullanımı için yumuşak bir sınır belirler (ulimit, kB biriminde sınırı varsayar)
r2(){ r2 $@$@;};r2 r2
Yığın hafızası isterken CPU ve RAM'i katlanarak kendiliğinden iki katına çıkaracak şekilde özyinelemeli bash işlev çağrısı çalıştırır .
Gördüğünüz gibi, 1GB'den fazlasını talep etmeye çalışırken durdu.
Not, -v
sanal bellek ayırma üzerinde çalışır (toplam, yani fiziksel + takas).
Kalıcı koruma
Sanal bellek ayırmayı sınırlamak için for as
eşdeğeridir .-v
limits.conf
Herhangi bir tek hatalı davranış sürecine karşı korumak için aşağıdakileri yapıyorum:
- Tüm işlemler için bir sabit adres alanı sınırı belirleyin.
address space limit = <physical memory> - 256MB
.
- Bu nedenle, açgözlü bellek kullanımı veya etkin bir döngü ve bellek sızıntısı olan tek bir işlem TÜM fiziksel belleği tüketemez.
- 256 MB tavan boşluğu, ssh veya bir konsol ile gerekli işlemler için mevcuttur.
Bir astar:
$ sudo bash -c "echo -e \"*\thard\tas\t$(($(grep -E 'MemTotal' /proc/meminfo | grep -oP '(?<=\s)\d+(?=\skB$)') - 256*2**10))\" > /etc/security/limits.d/mem.conf"
Doğrulamak için bu aşağıdakilerle sonuçlanır (örn. 16GB sistemde):
$ cat /etc/security/limits.d/mem.conf
* hard as 16135196
$ ulimit -H -v
161351960
Notlar:
- Yalnızca bellek kullanımıyla birlikte tek bir işleme geçmeye karşı hafifletir.
- Ağır bellek basıncına sahip çok işlemli bir iş yükünün daralmaya neden olmasını engellemeyecektir (o zaman cevap gruplarıdır).
rss
Sınırlar.conf dosyasında seçeneği kullanmayın . Daha yeni çekirdekler tarafından saygı duyulmaz.
- Muhafazakar.
- Teorik olarak, bir süreç spekülatif olarak çok fazla bellek talep edebilir, ancak sadece aktif olarak bir altkümeyi (daha küçük çalışma kümesi / yerleşik bellek kullanımı) kullanabilir.
- Yukarıdaki sabit sınır, bu tür işlemlerin iptal edilmesine neden olacaktır (Linux sanal bellek adres alanının aşırı yüklenmesine izin verdiğinden, aksi takdirde iyi çalışmış olsalar bile).
Daha Yeni CGruplar
Daha fazla kontrol sunar, ancak şu anda kullanımı daha karmaşıktır:
- Ulimit teklifini geliştirir.
memory.max_usage_in_bytes
fiziksel belleği ayrı ayrı hesaplayabilir ve sınırlayabilir.
- Halbuki
ulimit -m
ve / veya rss
in limits.conf
benzer işlevler sunması amaçlanmıştır, ancak çekirdek Linux 2.4.30'dan beri işe yaramıyor!
- İhtiyaç açılış, bazı çekirdek CGroup bayrakları etkinleştirmek için:
cgroup_enable=memory swapaccount=1
.
- Bu, Ubuntu 16.04 ile varsayılan olarak gerçekleşmedi.
- Muhtemelen ekstra muhasebe ek yükünün bazı performans etkileri nedeniyle.
- cgroup / systemd şeyler nispeten yenidir ve adil bir şekilde değişmektedir, bu yüzden akış yukarı akı Linux dağıtım sağlayıcılarının henüz kullanımı kolay hale getirmediğini ima etmektedir. 14.04LTS ve 16.04LTS arasında, cgroups kullanmak için kullanıcı alanı araçları değişti.
cgm
artık resmi olarak desteklenen kullanıcı alanı aracı gibi görünüyor.
- systemd birim dosyalarının ssh gibi önemli hizmetlere öncelik tanımak için önceden tanımlanmış "satıcı / dağıtım" varsayılanları henüz görünmüyor.
Mevcut ayarları kontrol etmek için:
$ echo $(($(cat /sys/fs/cgroup/memory/memory.max_usage_in_bytes) / 2**20)) MB
11389 MB
$ cat /sys/fs/cgroup/memory/memory.stat
...
Örneğin, tek bir işlemin belleğini sınırlamak için:
$ cgm create memory mem_1G
$ cgm setvalue memory mem_1G memory.limit_in_bytes $((1*2**30))
$ cgm setvalue memory mem_1G memory.memsw.limit_in_bytes $((1*2**30))
$ bash
$ cgm movepid memory mem_1G $$
$ r2(){ r2 $@$@;};r2 r2
Killed
RAM'i bir arka plan işlemi olarak çiğnediğini ve sonra öldürüldüğünü görmek için:
$ bash -c 'cgm movepid memory mem_1G $$; r2(){ r2 $@$@;};r2 r2' & while [ -e /proc/$! ]; do ps -p $! -o pcpu,pmem,rss h; sleep 1; done
[1] 3201
0.0 0.0 2876
102 0.2 44056
103 0.5 85024
103 1.0 166944
...
98.9 5.6 920552
99.1 4.3 718196
[1]+ Killed bash -c 'cgm movepid memory mem_1G $$; r2(){ r2 $@$@;};r2 r2'
Bellek isteklerinde üstel (2 gücü) büyümeye dikkat edin.
Gelecekte, SSH ve grafik yığını gibi önemli şeyler için "dağıtım / satıcılar" ın grup önceliklerini ve sınırlarını (systemd birimleri aracılığıyla) önceden yapılandırmayı görmeyi umuyoruz, böylece asla hafızadan aç kalmayacaklar.