Nasıl bu kadar yavaş değişebilir?


77

Her nasılsa 14 GB hafızayı değiştirdim. Suçluyu öldürdükten sonra tekrar tonlarca boş hafızam var, bu yüzden önemli verileri tekrar getirebileceğimi düşündüm . Böylece, 32 GB'ın 5 GB'ı kullanılmış ve 14 GB'ın takas alanı kullanılmış, koştum swapoff -a.... ve 4 saat sonra işin yaklaşık yarısı bitti.

Bu, 1 MB / sn'den daha düşük olduğu anlamına gelirken, 200 MB / sn'yi kolayca kopyalayabilirim. Takas kodum şifrelenmiş ancak hepsi normal bölümler ve aes-ni ile farkedilir bir CPU yüküne yol açmıyor (ve takas alanının doldurulması sadece birkaç dakika sürdü). Optimize etmek için özel bir neden olmadığını görüyorum ama bunun swapoffnasıl yavaşlayabileceğini merak ediyorum.


Sadece biraz daha veri eklemek: Ana belleğim 32 GB ve 4 sabit diskin her birinde 32 GB'lık takas alanım var (kesinlikle bir overkill, ama kimin umurunda?). Bütün takas alanı 5 dakikadan daha kısa bir sürede okunabilir (şifresi çözülebilir ve):

time -p sudo sh -c 'for i in /dev/mapper/cryptswap?; do md5sum $i & done; wait'
014a2b7ef300e11094134785e1d882af  /dev/mapper/cryptswap1
a6d8ef09203c1d8d459109ff93b6627c  /dev/mapper/cryptswap4
05aff81f8d276ddf07cf26619726a405  /dev/mapper/cryptswap3
e7f606449327b9a016e88d46049c0c9a  /dev/mapper/cryptswap2
real 264.27

Bir bölümün bir bölümünü okumak, hepsini okumaktan daha yavaş olamaz. Ancak bunun 1 / 10'u okumak yaklaşık 100 kat daha uzun sürüyor.

Her swapoffiki CPU sırasında da çoğunlukla boşta (bir çekirdeğin belki de% 10'u) ve disklerin de (LED'ler tarafından "ölçülen") olduğunu gözlemledim . Ayrıca takas alanlarının arka arkaya kapatıldığını gördüm.


1
Merak ediyorum, aynı olgu sistem değiştirilen sayfaları RAM'e geri yüklerken de ortaya çıkıyor mu? Örneğin, bir sistem diske askıya alınmış ve ardından başlatılıyorsa, her şey değiştirildi ve RAM'e geri yüklendi. Bana da çok yavaş geliyor.
Petr Pudlák

Tüm takas cihazları aynı önceliğe sahip mi?
Nils

@Petr Pudlák: Diske askıya alma işlemi biraz farklıdır, sadece RAM içeriğini takas alanındaki boş bir alana yazar ve bu (ve askıya alma işlemi) muhtemelen çok daha hızlıdır. Şifreli takas ile çalışmadığı için deneyemem.
maaartinus

@Nils: Evet, öncelik aynı ve disk ve onların bölümleri de aynı.
maaartinus

Bu daha garip yapar. Bu durumda, takas tüm disklerde çizgilidir - bu çok hızlı olmalıdır. Did iostat -d 5sırasında diskler üzerinde düşük IO göstermek swapoffde?
Nils

Yanıtlar:


53

Öncelikle, sabit diskinizden neler bekleyebileceğinize bir bakalım. Sabit sürücünüz art arda 200 MB / sn yapabilir . Zaman aramayı hesaba katarsanız, daha yavaş olabilir. Keyfi bir örnek seçmek için, Seagate'in modern 3TB disklerinden biri olan ST3000DM001'in özelliklerine bakın :

  • Maksimum sürekli veri hızı: 210 MB / s

  • Ortalama okuma isteyin: <8.5 ms

  • Sektör başına bayt: 4,096

Asla aramanız gerekmiyorsa ve takasınız diskin kenarına yakınsa, maksimum hızı = 210 MB / sn görmeyi bekleyebilirsiniz.

Ancak eğer takas verileriniz tamamen parçalanmışsa, en kötü senaryoda, okuduğunuz her sektör için etrafa bakmanız gerekir. Bu, yalnızca her 8,5 ms'de 4 KB veya 4 KB / 0.0085 = 470 KB / s okuyabileceğiniz anlamına gelir

Öyleyse yarasadan hemen çıkınca, aslında sabit disk hızlarına karşı koştuğunuz düşünülemez .


Bununla birlikte, swapoffçok yavaş çalışacak ve özellikle hızlı bir şekilde yazılmışlarsa (sıralı anlamına gelirse) sayfaları düzensiz okumak zorunda kalacak aptalca görünüyor . Ama bu sadece çekirdeğin nasıl çalıştığı olabilir. Ubuntu hata raporu # 486666 da aynı sorunu tartışıyor:

The swap is being removed at speed of 0.5 MB/s, while the
hard drive speed is 60 MB/s;
No other programs are using harddrive a lot, system is not under
high load etc.

Ubuntu 9.10 on quad core.

Swap partition is encrypted.
Top (atop) shows near 100% hard drive usage
  DSK | sdc | busy 88% | read 56 | write 0 | avio 9 ms |
but the device transfer is low (kdesysguard)
  0.4 MiB/s on /dev/sdc reads, and 0 on writes

Cevaplardan biri:

It takes a long time to sort out because it has to rearrange and flush the
memory, as well as go through multiple decrypt cycles, etc. This is quite
normal

Hata raporu çözülmeden kapatıldı.

Mel Gorman'ın " Linux Sanal Bellek Yöneticisini Anlamak " adlı kitabı güncel değil, ancak bunun yavaş bir işlem olduğunu kabul ediyor:

Bir alanı devre dışı bırakmaktan sorumlu olan fonksiyon, tahmin edilebileceği gibi çağrılır sys_swapoff(). Bu fonksiyon esas olarak güncelleme ile ilgilidir swap_info_struct. Her sayfalık çalışmada dışarı sayfasında çağrı başlıca görevi sorumluluğundadır try_to_unuse()olduğu son derece pahalı.

2007'den itibaren Linux çekirdeği posta listesinde " takas hızını arttırma " konusunu konu alan biraz daha fazla tartışma var.


swapoffNadiren kullanıldığından , muhtemelen genellikle göz ardı edilen ilginç bir soru . Ben bunu gerçekten izini istiyorsa, ilk adım daha dikkatli disk kullanım alışkanlıklarına izlemeye çalışıyorum olacağını düşünüyorum (belki birlikte atop, iostathatta daha güçlü araçlar gibi perfya systemtap). Aranacak şeyler aşırı arama, küçük G / Ç işlemleri, sürekli yeniden yazma ve veri taşıma vb. Olabilir.


5
Mükemmel açıklama Parçalanan hafızanın çoğunu atlatmanın ve hızlı bir şekilde takas belleğin büyük bölümlerini çekerek
Brandon DuPree

Bu sadece parçalanma / arama zamanı değil. Değişimim SSD'de ve rastgele okumalar çok hızlı, yine de swapoff komutu olması gerekenden çok daha yavaş ve SSD yüküm yaklaşık% 1 kullanımda oturuyor. Çekirdekte veya takas işlemlerinde (~% 90-100 CPU kullanan) liste yürüyüşü yapıldığından şüpheleniyorum. Tabii ki tüm işler sırayla yapılırsa ve disk yavaş çalışırsa, önemli ölçüde ekleyebilir.
Thomas Guyot-Sionnest

33

Aynı sorunu bir SSD'ye sahip olan dizüstü bilgisayarımla da yaşıyorum.

Alternatif bir açıklama buldum . İşte bir alıntı

Şimdi çalışma şekliyle, takas alanı takas bölümündeki her bir değiştirilen bellek sayfasına bakar ve onu kullanan tüm programları bulmaya çalışır. Onları hemen bulamazsa, onları bulmak için çalışan her programın sayfa tablolarına bakacaktır. En kötü durumda, bölümdeki her değiştirilen sayfa için tüm sayfa tablolarını kontrol eder. Bu doğru - aynı sayfa tabloları tekrar tekrar kontrol edilir.

Bu yüzden başka bir şeyden çok bir çekirdek problemidir.


Hayır, çekirdek problem değil IMHO. Bu nasıl swapoffuygulanır? Takas işlemi sona erdiğinde çok uzun sürmez.
Marki555,

15
Çekirdekte olan bir takas uygulamasının sorunu - çekirdeğin sorunu! Gördüğünüz strace swapoffkadarıyla tek yapmanız gereken swapoffsistem çağrısı yapmak.
Nick Craig-Wood,

1
48GB RAM (32 çekirdekli) olan bir sunucum var, 6GB ücretsiz hata takası 0.7GB kullandım. swappiness = 10, 0 yapmaya çalıştı ve aynı zamanda ne olacağını görmek için swapoff'u denedi. takas süresi yaşını alır, muhtemelen 30 dakika sürer ve takası çok yavaş bir şekilde serbest bırakır. Neredeyse hiçbir yük altında SSD var ve CPU benzer, bir cpu% 100 alır takas işlemi bekliyoruz.
sorin

1
Takas işleminin nasıl uygulandığı (çekirdekte) sorunu. Birkaç yıl önce çekirdek-dev'te çok daha iyi bir yaklaşım hakkında tartışmalar yapıldı, ancak bunun bir köşe olayı olduğunu ve bunu değiştirme çabasını istemediklerini söylüyorlar.
Marki555,

7
1 TB RAM (evet, TB) ve 2 GB takas (aptal SAP gereksinimi) takas sunucusunda bu takas, 2 GB'ın% 5'ini serbest bırakmak için 12 saat sürdü (% 100'de 1 işlemci çekirdeği ile).
Marki555,

22

Evet, swapoffmekanizma korkunç derecede verimsiz. Çözüm geçicidir: işlemler üzerinde yineleme yapmak yerine, değiştirilen sayfalarda yineleme yapmak. Bu python betiğini kullanın (Bağlı değilim):

git clone https://github.com/wiedemannc/deswappify-auto

Servis modu çalışma modunun yalnızca genellikle hazırda bekletilen masaüstü / dizüstü bilgisayarlar için olduğunu unutmayın. Bir sunucu sisteminde bir arka plan programı olarak çalıştırmam - sadece ön planda çalıştır, bazı işlemlerle ilgilendiğini bildirene kadar bekle, sonra durdur ve dene:

swapoff /dev/x

Sayfaların çoğu artık hem takas halinde hem de bellekte mevcut olduğundan, swapoffyapacak çok şeyi var ve artık cayır cayır yanan hızlı olması gerekiyor (yüzlerce MB / sn gördüm).

Tarihçe bölümü ileri

Yukarıda belirtilen python betiği, bu cevabın geri kalanını temel alır ve bu da benim jlong tarafından yazılan bu eski cevabımdaki gelişmemdi . Senaryo çok daha güvenli olduğundan , cevabımın kalanını sadece savunma hattının son denemesi olarak denemenizi tavsiye ederim :

perl -we 'for(`ps -e -o pid,args`) { if(m/^ *(\d+) *(.{0,40})/) { $pid=$1; $desc=$2; if(open F, "/proc/$pid/smaps") { while(<F>) { if(m/^([0-9a-f]+)-([0-9a-f]+) /si){ $start_adr=$1; $end_adr=$2; }  elsif(m/^Swap:\s*(\d\d+) *kB/s){ print "SSIZE=$1_kB\t gdb --batch --pid $pid -ex \"dump memory /dev/null 0x$start_adr 0x$end_adr\"\t2>&1 >/dev/null |grep -v debug\t### $desc \n" }}}}}' | sort -Vr | head

Bu belki 2 saniye çalışır ve aslında bir şey yapmaz, sadece ilk 10 hafıza segmentlerini (aslında daha bir gömlekler yazdırır listelemek; evet ben do kopyalayıp yapıştırma, sadece komutları incelemek riski kabul; bir gömlekler seviyorum kabuğunuzu, bunlar aslında takas okuyacak).

...Paste the generated one-liners...
swapoff /your/swap    # much faster now

Tek astar ana (benim için) çok fazla / proc okuyor olması dışında güvenli.

Manuel sınavınız için hazırlanan alt komutlar güvenli değildir . Her komut, takas işleminden bir hafıza parçasını okumak için bir işlemi asar. Bu yüzden duraklamalara tolerans göstermeyen işlemlerden güvensizdir. Gördüğüm transfer hızları dakikada 1 gigabayt seviyesindeydi. (Yukarıda belirtilen python betiği bu eksikliği giderdi).

Diğer bir tehlike, sisteme çok fazla bellek baskısı koymaktır; free -m

Bu ne işe yarıyor?

for(`ps -e -o pid,args`) {

  if(m/^ *(\d+) *(.{0,40})/) { 
    $pid=$1; 
    $desc=$2; 

    if(open F, "/proc/$pid/smaps") { 

      while(<F>) { 

        if(m/^([0-9a-f]+)-([0-9a-f]+) /si){ 
          $start_adr=$1; 
          $end_adr=$2; 
        } elsif( m/^Swap:\s*(\d\d+) *kB/s ){
          print "SSIZE=$1_kB\t gdb --batch --pid $pid -ex \"dump memory /dev/null 0x$start_adr 0x$end_adr\"\t2>&1 >/dev/null |grep -v debug\t### $desc \n" 
        }
      }
    }
  }
}

Bu perl senaryonun çıktı dizisidir gdbkomutları dump memory (range)bellekten takas sayfaları hatırlayın.

Çıktı boyutla başlar, bu nedenle boyuta göre en | sort -Vr | headbüyük 10 segmenti (SSIZE) elde etmek için enlemesine geçmek kolaydır . -VVersiyon numarası-uygun sıralama için standları, ama benim amaç için çalışır. Sayısal sıralama nasıl yapılacağını çözemedim.


Sayısal sıralama burada kullanınsort -t = -k 2n
Stéphane Chazelas

9
Proses hafızasına göz atmak için gdb kullanmaya gerek yoktur (en azından son zamanlarda çekirdeklerde). Kişi /proc/$pid/memdoğrudan açabilir , arayabilir ve okuyabilir. İşte PoC'unuz büyük ölçüde snippet'inize dayanıyor: gist.github.com/WGH-/91260f6d65db88be2c847053c49be5ae Bu şekilde işlem durmaz , AFAIK bu konuda herhangi bir tehlike yaratmamalıdır .
WGH

10

Takas sırasında, kullanımda bir takas yuvası tespit edilirse, çekirdek ilk önce sayfa içinde yer değiştirir. Unuse_process () işlevi daha sonra yeni girilen sayfaya karşılık gelen tüm sayfa tablosu girişlerini bulmaya çalışır ve sayfa tablolarında gerekli güncellemeleri yapar. Arama kapsamlı ve çok zaman alıyor: tüm bellek tanımlayıcılarını (tüm sistemin) ziyaret ediyor ve sayfa tablosu girişlerini tek tek inceler.

Lütfen "Linux Çekirdeği 3. sürümü anlama", sayfa 724'e bakın.

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.