Vm.overcommit_memory yapılandırmasının etkileri


41

CentOS 5.4 üzerinde çalışan VPS web sunucum (Linux çekirdeği 2.6.16.33-xenU) düzensiz olarak (ayda bir kez veya birkaç hafta sürebilir), oom-katil tekme atması nedeniyle yanıt vermiyor. Sunucunun izlenmediğini gösteriyor normalde hafızası tükenir, sadece sık sık.

Aşağıdaki sysctl ayarlarını kullanarak fazla çalışmayı daha iyi yönetmek için çekirdeği yapılandırmayı tartışan bu sayfaya işaret eden birkaç blog okudum :

vm.overcommit_memory = 2
vm.overcommit_ratio = 80

Bunu anladım (yanlış olabilir, ancak açıklığa kavuşturmak için kanonik bir tanım bulamıyorum), bunun çekirdeğin fiziksel belleği +% 80'inin ötesine takması üzerine çekirdeği fazla ayırmasını engellemesidir.

Ancak, ben de okudum bazı bu ayarlar iyi bir fikir olmadığını düşündüren diğer kaynakları - Bu yaklaşımın eleştirmenler varsayımı ki "yerine bu kludge girişimi yerine, sistem kırmak için şeyler yapmaz" diyerek gibi görünüyor olsa da nedensellik daima bilinir.

Öyleyse sorum şu, yaklaşık 10 düşük trafik alanını barındıran bir Apache2 web sunucusu bağlamında, bu yaklaşımın avantajları ve dezavantajları nelerdir? Özel durumumda, web sunucusu 524Mb RAM, 1024Mb takas alanına sahip. Bu zamanın büyük çoğunluğu için yeterli görünüyor.

Yanıtlar:


32

overcommit_ratio80 olarak ayarlanması muhtemelen doğru eylem değildir. Değeri 100'den küçük bir değere ayarlamak neredeyse her zaman yanlıştır.

Bunun nedeni, linux uygulamalarının gerçekten ihtiyaç duyduklarından fazlasını ayırmasıdır. Bir çift karakterli metin dizisini saklamak için 8kb ayırdıklarını söyleyin. İşte şu anda birkaç KB kullanılmamış. Uygulamalar bunu çok yapar ve fazla ödün vermenin amacı budur.

Bu yüzden, temelde 100'de aşırı devir ile çekirdek, uygulamaların sahip olduğunuzdan daha fazla bellek ayırmasına izin vermeyecektir (takas + ram). 100'den daha düşük bir değere ayarlanması, tüm belleğinizi asla kullanmayacağınız anlamına gelir. Bu ayarı belirleyecekseniz, önceden belirtilen senaryo nedeniyle 100'den daha yükseğe ayarlamanız gerekir, bu oldukça yaygındır.

Şimdi, OOM katilinin tetiklenmesiyle ilgili sorunlarınız için, elle aşırı hız ayarının yapılması bu sorunu çözmeyecektir. Varsayılan ayar (sezgisel belirleme) oldukça zekicedir.

Bunun gerçekten sorununun nedeni olup olmadığını görmek istiyorsanız /proc/meminfo, OOM katilinin ne zaman çalıştığına bakın. Bunun Committed_ASyakın CommitLimit, ancak freehala boş belleği gösterdiğini görüyorsanız, evet, senaryo için fazla ödemeyi manuel olarak yapabilirsiniz. Bu değerin çok düşük ayarlanması, OOM katilinin hala yeterince boş belleğiniz olduğunda uygulamaları öldürmeye başlamasına neden olur. Çok yüksek bir değere ayarlanması rastgele uygulamaların ayrılmış bellek kullanmaya çalıştıklarında ölmelerine neden olabilir, ancak gerçekten kullanılamazlar (tüm bellek tükendiğinde).


1
Teşekkürler - Overcommit_ratio ile ne olacağını görmek için 100'e ayarlanmış şeyleri deniyorum. Başlıca sorunum, oom-katil başladığında, sunucuya erişmemi ve ne olup bittiğini görmemi engellemek için her zaman sshd'yi öldürmesi. Sanırım gerçekte ihtiyacım olan şey, katilin çalışmasını engellemek ve ... ... ne zaman çalışacağınıolmak için bir şeyler kaydetmektir, böylece sorunun nedenini bulabilirim.
dunxd

4
@dunxd /proc/<PID>/oom_score_adjbu amaçla kullanabilirsiniz . Örneğin, oom_score_adj sshd için -1000 olarak ayarlanırsa, oom katili bir şeyi öldürmek istediğinde sshd'yi asla hedeflemez. Oom katilini durdurmak tamamen iyi bir fikir değil, o zaman programlarınız hafızayı bozamaz ve yine de ölürler.
Patrick,

4
@dunxd, kalıtsaldır. init betiğinizin kendisinin ayarlamasını isteyin; init betiği tarafından başlatılan her şey onu miras edin.
Patrick

4
4 KB örneğiniz yanlış. Sanal bellek sayfalarla birlikte kullanılır ve Linux altındaki bir sayfanın (en küçük) boyutu 4 KB'dir. Bu, birkaç karakterin depolanmasının, üst ödeme ayarlarından bağımsız olarak bir yere eşleştirilmesi için 4 KB gerektirdiği anlamına gelir. Taahhüt yerine bellek için uygun bir örnek, örneğin 10 KB ayırır ve yalnızca ilk 4100 baytı kullanır. Bu, iki 4 KB sayfanın verileri depolaması gerektiği ve fazladan bir sayfanın kullanılmadığı anlamına gelir. Aşırı yüklenmeyen sistemler her zaman talebin gelmesi durumunda veri depolamaya hazır üçüncü sayfalara sahip olacaklardır;
jlliagre

2
/ proc / self, geçerli sürece işaret eder, bu nedenle / proc / self / oom_score_adj, geçerli işlemin oom_score_adj değerini değiştirmek için kullanılabilir.
r_2

23

9.6 Dokümandaki "Aşırı Taahhüt ve OOM" ifadesi, @dunxd'nin, özellikle fazla mesaiye izin vermenin tehlikeleri ile ilgili bir grafik olduğunu göstermektedir. Ancak, 80benim için de ilginç görünüyordu, bu yüzden birkaç test yaptım.

Bulduğum şey, overcommit_ratioTÜM süreçler için mevcut olan toplam RAM'i etkilediği. Kök işlemler normal kullanıcı işlemlerinden farklı şekilde ele alınmaz.

Oranı 100veya altına ayarlamak, geri dönüş değerlerinin malloc/sbrkgüvenilir olduğu klasik anlambilimi sağlamalıdır . Oranları daha düşük ayarlamak, 100önbellekleme ve benzeri işlemler gibi işlem dışı etkinlikler için daha fazla RAM ayırmanın bir yolu olabilir.

Yani, bilgisayarımda 24 GiB RAM, takas devre dışı bırakılmış, 9 GiB kullanımda, topgösterilen

Mem:  24683652k total,  9207532k used, 15476120k free,    19668k buffers
Swap:        0k total,        0k used,        0k free,   241804k cached

İşte bazı overcommit_ratioayarlar ve ram-tüketici programımın ne kadar RAM alabileceğini (her sayfaya dokunmak) - her durumda program bir kez mallocbaşarısızlıkla temiz bir şekilde çıktı .

 50    ~680 MiB
 60   ~2900 MiB
 70   ~5200 MiB
100  ~12000 MiB

Aynı anda birden fazla kullanıcı çalıştırmak, bazıları root kullanıcısı olsa bile, birlikte harcadıkları toplam miktarı değiştirmedi. Son 3+ GiB ya da öylesini tüketememesi ilginç; freeçok burada gösterilenden altına düşmedi:

Mem:  24683652k total, 20968212k used,  3715440k free,    20828k buffers

Deneyler dağınıktı - tüm RAM kullanımdayken malloc kullanan herhangi bir şey çökme eğilimindedir, çünkü birçok programcı C'deki malloc başarısızlıklarını kontrol etme konusunda korkunç, bazı popüler koleksiyon kütüphaneleri bunu tamamen görmezden gelir ve C ++ ve diğer bazı diller bile daha da kötüsü.

Gördüğüm hayali RAM'in ilk uygulamalarının çoğu , genellikle çok çok daha küçük fork()olan exec()bazı destek programlarına ihtiyaç duydukları tek bir büyük sürecin -% 51 + kullanılabilir bellek diyelim - olması gereken çok özel bir durumla ilgiliydi. Yazma-yazma anlambilimine sahip işletim sistemleri izin verecek fork(), ancak şart koşulu ile eğer çatallı işlem gerçekten çok fazla bellek sayfasını değiştirmeye çalıştıysa (her biri ilk büyük işlemden bağımsız olarak yeni bir sayfa olarak başlatılmalıdır) öldürülmek zorunda kalacaktı. Ana süreç sadece daha fazla hafıza tahsis edildiğinde tehlikedeydi ve bazı durumlarda sadece başka bir işlemin ölmesini bekleyip sonra da devam ederek bitiyordu. Çocuk süreci genellikle kendini yeni (genellikle daha küçük) bir programla değiştirdi.exec() ve daha sonra şartsızdı.

Linux'un aşırı alım konsepti, hem fork()gerçekleşmesine hem de tek işlemlerin toplu olarak toplanmasına izin verilmesine izin veren aşırı bir yaklaşımdır . OOM katili kaynaklanan ölüm bile programlara, eş zamanlı gerçekleşmeyebilir yapmak sorumlu kolu bellek ayırmayı. Genel olarak sistem genelindeki aşırı görevden ve özellikle de oom katilden nefret ediyorum - bu, kütüphaneleri etkileyen ve onları kullanan her uygulama aracılığıyla hafıza yönetimine kötü niyetli bir bakım yaklaşımı teşvik ediyor.

Oranı 100 olarak ayarlamanızı ve takas bölümünün olmasını, genellikle yalnızca büyük süreçler tarafından kullanılmaya başlanmasını öneririm - bu genellikle takas alanlarının bir kısmının sadece küçük bir kısmını kullanır ve böylece Proseslerin büyük çoğunluğunu OOM öldürücü yanlış kullanımından korumak. Bu, web sunucunuzu rastgele ölümden korumalı ve mallocsorumlu bir şekilde ele almak için yazılmışsa , kendisini öldürmekten bile güvenli olmalı (ancak ikinciye bahis yapmayın).

Bu, içinde kullanıyorum anlamına gelir /etc/sysctl.d/10-no-overcommit.conf

vm.overcommit_memory = 2
vm.overcommit_ratio = 100

Vm.overcommit_memory öğesini 2'ye tutmayı tavsiye eder misiniz?
Ut xD

1
İyi not - gerçekten kullandığım şey bu; Sanırım
Alex North-Keys
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.