Linux bellek parçalanması


20

Linux'ta bellek parçalanmasını tespit etmenin bir yolu var mı? Bunun nedeni, bazı uzun süre çalışan sunucularda performans düşüşünü fark ettiğimden ve yalnızca işlemi yeniden başlattıktan sonra daha iyi performans gördüğümden kaynaklanıyor. Linux büyük sayfa desteği kullanırken daha çok fark ettim - linux'daki büyük sayfalar parçalanmaya daha mı meyilli?

Özellikle / proc / buddyinfo'ya baktım. Bakmak için daha iyi bir yol olup olmadığını bilmek istiyorum (sadece CLI komutları değil, herhangi bir program veya teorik arka plan yapardı).


Sadece hızlı komut satırı çözümlerine bakmıyorum, herhangi bir basit program / teori de yapacak. Bu nedenle, serverfault sormadım.
Raghu

1
Burada bir noktayı anlamıyorum. Anladığım kadarıyla bellek parçalanması, bellek eksikliğine ve bunun sonucunda da bellek ayırma hatalarına yol açmalıdır. Ancak performans düşüşünü soruyorsunuz. Diske çok fazla belleğiniz olduğu için mi? Ve eğer öyleyse vmstat, alana ne verir so?

@skwllsp - Cevabımı daha spesifik olacak şekilde düzenledi.
Tim Post

@Raghu - Ben en çok sistem yöneticileri bellek yönetim farklı davranır, ancak, yapmak çekirdek kodunu değiştirmek istemem yetenekli Linux yöneticileri en az bir bakış bilmeli nasıl Linux belleği yönetir. Bu soru gerçekten on line. Sorunuzu cevaplayan (cevabımda) kod öneremediğim için taşınmaya oy verdim. / Proc'tan veya procitten okumak vmstatyaygın bir kullanıcı deneyimi. Aynı şeyi yapmak için bir program yazıyorsanız , bu farklı olurdu. Bu bilgiyi toplamak için bash kullanmak istiyorsanız, sorunuzu düzenleyin, kapatılmayacak :)
Tim Post

@Tim - Bilmek istediğim sadece bash / cli komutları değil, kıyaslama prosedürümde bana yardımcı olacak bilgilere ihtiyacım vardı (sonuçları analiz etmek, çalıştırmak için değil).
Raghu

Yanıtlar:


12

etiketine cevap veriyorum . Cevabım sadece Linux'a özgü .

Evet, devasa sayfalar parçalanmaya daha yatkındır. Belleğin iki görünümü vardır, işleminiz (sanal) ve çekirdeğin yönettiği (gerçek). Herhangi bir sayfa büyüdükçe, özellikle de hizmetiniz varsayılan olarak onlardan daha fazla bellek ayıran ve daha fazla bellek ayıran diğerlerini desteklemesi gereken bir sistemde çalışırken, komşularını gruplandırmak (ve onunla birlikte tutmak) daha zor olacaktır. aslında sonunda kullanmak.

Çekirdeğin (gerçek) verilen adresleri eşlemesi özeldir. Kullanıcı alanının çekirdeği onları sunduğu gibi görmesinin çok iyi bir nedeni var, çünkü çekirdeğin kullanıcı alanını karıştırmadan fazla işlem yapabilmesi gerekiyor. İşleminiz , çekirdeğin aslında sahne arkasındaki bellekle ne yaptığından habersiz, çalışacak güzel, bitişik bir "Disneyfied" adres alanı alır .

Uzun süredir çalışmakta olan sunucularda düşük performans görmenizin nedeni büyük olasılıkla, açıkça kilitlenmemiş (örneğin mlock()/ mlockall()veya posix_madvise()) ve bir süredir değiştirilmemiş olan ayrılmış bloklar sayfalara ayrıldığından, hizmetinizin okunması gerektiğinde diske kayması anlamına gelir onlar. Bu davranışı değiştirmek, işleminizi kötü bir komşu yapar , bu nedenle birçok kişi RDBMS'lerini web / php / python / ruby ​​/ whatever'den tamamen farklı bir sunucuya koyar. Bunu düzeltmenin tek yolu, bitişik bloklar için rekabeti azaltmaktır.

Parçalanma yalnızca A sayfası bellekte olduğunda ve B sayfası değiş tokuşa taşındığında (çoğu durumda) gerçekten fark edilir. Doğal olarak, hizmetinizi yeniden başlatmak bunu `` iyileştiriyor '' gibi görünebilir, ancak sadece çekirdek, henüz tahsis edilen oranın sınırları içinde yeni tahsis edilmiş blokları (şimdi) sayfadan çıkarma fırsatına sahip olmadığı için.

Aslında, yüksek bir yük altında 'apache'nin yeniden başlatılması (diyelim) büyük olasılıkla diğer hizmetlerin sahip olduğu blokları doğrudan diske gönderecektir. Yani evet, 'apache' kısa bir süre için iyileşirdi, ama 'mysql' acı çekebilir .. en azından çekirdek yeterli fiziksel hafıza eksikliği olduğunda çekirdek eşit derecede acı çekene kadar.

Daha fazla bellek ekleyin veya talepkar malloc()tüketicileri ayırın :) Sadece bakmanız gereken parçalanma değil.

vmstatNerede depolandığına dair genel bir bakış elde etmeye çalışın .


Cevap için teşekkür ederim. Ne kadar iyi (sysbench kullanarak) görmek için mysql - innodb buffer pool - için büyük sayfalar (boyut = 2048KB) kullanıyordum. Başlangıçta süreç çalışma süresi (ve hatta sistem çalışma süresi) düşük olduğunda, çok iyi sonuçlar veriliyordu. Ancak, performansı birkaç turda düşmeye başladı. Bahsettiğiniz sayfa ile ilgili olarak, kesinlikle yüksek bir VM etkinliği fark ettim, ancak bunun benchmark ve innodb log sifonu nedeniyle olabileceğini varsaydım (vm etkinliği, büyük sayfalarda onsuz daha yüksek). Ayrıca vm.swappiness 1 olarak ayarladım.
Raghu

Göre ince kılavuzda , "Büyük sayfalar bellek basınç altında takas edilemez." Bunun w / r / t standart bellekte iyi bir cevap olduğunu düşünüyorum ancak büyük sayfalar için değil.
Dan Pritts

5

Çekirdek

Geçerli parçalanma indeksini almak için şunu kullanın:

sudo cat /sys/kernel/debug/extfrag/extfrag_index

Çekirdek belleğini birleştirmek için çalıştırmayı deneyin:

sysctl vm.compact_memory=1  

Ayrıca Şeffaf Büyük Sayfaları (THP olarak da bilinir) kapatmayı ve / veya değiştirmeyi devre dışı bırakmayı (veya azaltmayı swappiness) deneyin .

Kullanıcı alanı

Kullanıcı alanı parçalanmasını azaltmak için farklı bir ayırıcıyı denemek isteyebilirsiniz, örneğin jemalloc( size ayırıcı iç parçalanmasına bir iç verecek harika içgözleme yetenekleri vardır ).

Programınızı onunla yeniden derleyerek veya yalnızca aşağıdakileri çalıştırarak özel malloc'a geçebilirsiniz LD_PRELOAD: LD_PRELOAD=${JEMALLOC_PATH}/lib/libjemalloc.so.1 app ( THP ve bellek belleği ayırıcıları arasındaki etkileşimlere dikkat edin )

Bellek parçalanmasıyla biraz ilgisi olmasa da (ancak bellek sıkıştırma / taşıma işlemine bağlı), muhtemelen her NUMA düğümü için bir tane olmak ve bunları kullanarak bağlamak için hizmetinizin birden çok örneğini çalıştırmak istiyorsunuz numactl.


1
Takasın devre dışı bırakılmasının neden yardımcı olabileceğini düşünüyorsunuz? Benim için takasın devre dışı bırakılmasının daha da zarar görmesi daha olası görünüyor.
kasperd

1
Orijinal gönderide yeterli bilgi olmadığı için, işlem sadece sızıntı yapıyor ve değiştirmeye başlıyor. Ayrıca hemen hemen herhangi bir üretim sistemi (mb sadece öğrenciler için paylaşılan iş istasyonları için) takas kullanmak için herhangi bir meşru neden görmüyorum.
SaveTheRbtz

2
Yeterli takas alanına sahip olmak performansı artıracaktır. Eğer takas alanınız yetersizse karşılaşacağınız performans sorunları takas yapabilmek için yeterli sebeptir.
kasperd

1
@SaveTheRbtz Bir üretim sisteminde takas kullanmanın iyi bir nedeni, sisteme yalnızca yararlı olduklarını düşünürse kullanacağı daha fazla seçenek sunmasıdır. Ayrıca, saatlerce erişilmeyen (ve hiçbir zaman erişilemeyen) değiştirilmiş sayfaların değerli fiziksel bellekten çıkarılmasına izin verir. Son olarak, sistemin kullanıldığından çok daha fazla belleğin saklandığı durumları düzgün bir şekilde ele almasını sağlar.
David Schwartz

2
"sadece yararlı olduklarını düşünüyorsa" - ek sezgisel ekler ve sistemi daha az öngörülebilir kılar. Ayrıca sayfa değiştirme algoritmaları (takas ve anonim olarak kullanılır mmap) farklı çekirdeklerde (örn. Linux ve FreeBSD) veya aynı işletim sisteminin farklı sürümlerinde (2.6.32 vs 3.2 vs 3.10) farklı şekilde uygulanır. ..] [...] fiziksel bellekten çıkarılacak "- bu bellek sızıntılarını gizleyecektir. "kullanılandan çok daha fazla bellek ayrılmış durumda ele" - yavaş sistem aşağı sisteme göre çok daha kötü, bu yüzden "aklı başında" sorgulanabilir.
SaveTheRbtz

4

Büyük sayfaların kullanılması Linux'ta fazladan bellek parçalanmasına neden olmamalıdır; Büyük sayfalar için Linux desteği yalnızca paylaşılan bellek içindir (shmget veya mmap aracılığıyla) ve kullanılan büyük sayfalar özel olarak bir sistem yöneticisi tarafından istenmeli ve önceden konumlandırılmalıdır. Hafızaya girdikten sonra, orada sabitlenirler ve değiştirilmezler. Bellek parçalanması karşısında devasa sayfalarda geçiş yapmanın zorluğu, tam olarak neden belleğe sabitlenmiş olmalarıdır (2MB büyük bir sayfa tahsis ederken, çekirdek, var olmayan 512 bitişik ücretsiz 4KB sayfası bulmalıdır).

Büyük sayfalarda Linux belgeleri: http://lwn.net/Articles/375098/

Bellek parçalanmasının büyük sayfa tahsisinin yavaş olmasına (ancak büyük sayfaların bellek parçalanmasına neden olmadığı yerde ) neden olabileceği bir durum vardır ve bu, sisteminiz bir uygulama tarafından istenirse büyük sayfaların havuzunu büyütecek şekilde yapılandırılmışsa oluşur. / Proc / sys / vm / nr_overcommit_hugepages / proc / sys / vm / nr_hugepages değerinden büyükse, bu olabilir.


Gerçekten de - ve genel olarak performansa yardımcı olmalı, çünkü TLB eksiklerini önleyecektir (açıklama için ilgili makaleye bakın).
Dan Pritts

0

Orada /proc/buddyinfoçok kullanışlıdır. Bu Python betiğinin yapabileceği gibi güzel bir çıktı biçiminde daha kullanışlıdır:

https://gist.github.com/labeneator/9574294

Büyük sayfalar için 2097152 (2MiB) boyutunda veya daha büyük bazı ücretsiz parçalar istiyorsunuz. Saydam büyük sayfalar için, çekirdeklerden bazıları istendiğinde otomatik olarak sıkıştırılır, ancak kaç tane alabileceğinizi görmek istiyorsanız, o zaman kök çalıştırılır:

echo 1 | sudo tee /proc/sys/vm/compact_memory

Ayrıca evet, büyük sayfalar parçalanma için büyük sorunlara neden olur. Ya büyük sayfalar elde edemezsiniz, ya da bunların varlığı, çekirdeğin biraz almaya çalışmak için çok fazla zaman harcamasına neden olur.

Benim için çalışan bir çözümüm var. Birkaç sunucuda ve dizüstü bilgisayarımda kullanıyorum. Sanal makineler için harika çalışıyor.

Bu kernelcore=4Gseçeneği Linux çekirdek komut satırınıza ekleyin. Sunucumda 8G kullanıyorum. Sayıya dikkat edin, çünkü çekirdeğinizin o hafızanın dışında bir şey tahsis etmesini engelleyecektir. Çok fazla soket ara belleğine ihtiyaç duyan veya akış diskinin yüzlerce sürücüye yazdığı sunucular bu şekilde sınırlı olmaktan hoşlanmaz. Döşeme veya DMA için "sabitlenmesi" gereken bellek ayırma bu kategoridedir.

Daha sonra diğer belleğiniz "taşınabilir" hale gelir, bu da büyük sayfa tahsisi için güzel parçalara sıkıştırılabileceği anlamına gelir. Artık şeffaf büyük sayfalar gerçekten olması gerektiği gibi çalışabilir. Çekirdek daha fazla 2M sayfaya ihtiyaç duyduğunda 4K sayfaları başka bir yere yeniden eşleyebilir.

Ve bunun sıfır kopya doğrudan IO ile nasıl etkileşime girdiğinden tam olarak emin değilim. "Hareketli bölge" deki belleğin sabitlenmesi beklenmemektedir, ancak doğrudan bir IO talebi DMA için tam olarak bunu yapacaktır. Kopyalayabilir. Yine de hareketli bölgeye sabitleyebilir. Her iki durumda da muhtemelen tam olarak istediğiniz şey değildir.

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.