it-swarm-eu.dev

Jak může být swapoff tak pomalý?

Nějak jsem náhodou vyměnil 14 GB paměti. Po zabití viníka mám opět spoustu volné paměti, takže jsem si myslel, že bych mohl přinést důležitá data znovu. Takže s 5 GB z 32 GB použitého a 14 GB využitého swapového prostoru jsem běžel swapoff -a.... ao 4 hodiny později byla dokončena asi polovina práce.

To znamená méně než 1 MB/s, zatímco mohu snadno kopírovat 200 MB/s. Můj swap je šifrován, ale stejně tak jsou to všechny normální oddíly a s aes-ni to nevede k žádnému viditelnému zatížení CPU (a vyplnění swapového prostoru trvalo jen pár minut). Vidím, že neexistuje žádný zvláštní důvod k optimalizaci swapoff, ale zajímalo by mě, jak by to mohlo být tak pomalé?


Jen přidávám další data: Moje hlavní paměť je 32 GB a já mám 32 GB swapového prostoru na každém ze 4 pevných disků (jistě přebytek, ale koho to zajímá?). Celý odkládací prostor lze (dešifrovat a) přečíst za méně než 5 minut:

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

Čtení části oddílu nemůže být pomalejší než čtení všeho. Přesto čtení asi 1/10 trvá přibližně 100krát déle.

Zjistil jsem, že během swapoff byl CPU většinou nečinný (asi 10% jednoho jádra), a tak byly také disky ("měřeny" pomocí LED). Také jsem viděl, že odkládací prostory byly vypnuty jeden po druhém.

82
maaartinus

Nejprve se podívejme na to, co můžete od pevného disku očekávat. Váš pevný disk umí 200 MB/s postupně. Když zohledníte dobu hledání, může to být mnohem pomalejší. Chcete-li vybrat libovolný příklad, podívejte se na specifikace jednoho z moderních 3TB disků Seagate, ST3000DM001 :

  • Maximální trvalá přenosová rychlost: 210 MB/s

  • Průměrná hodnota vyhledávání: <8,5 ms

  • Bajty na sektor: 4 096

Pokud nikdy nepotřebujete hledat a pokud je váš swap blízko okraje disku, můžete očekávat, že uvidíte maximální rychlost = 210 MB/s

Pokud jsou však vaše swapová data zcela roztříštěná, v nejhorším případě budete muset hledat každý sektor, který čtete. To znamená, že můžete číst 4 KB každých 8,5 ms, nebo 4 KB/0,0085 = 470 KB/s

Takže hned po pálce to není nepředstavitelné, že ve skutečnosti běžíte proti rychlosti pevného disku.


Zdá se však hloupě, že swapoff by běžel tak pomalu a musel číst stránky mimo řád, zejména pokud byly napsány rychle (což znamená, že jsou v pořádku). Ale to může být právě to, jak jádro funguje. Hlášení chyb Ubuntu # 486666 popisuje stejný problém:

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

Jedna z odpovědí byla:

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

Hlášení o chybě bylo uzavřeno.

Kniha Mel Gormana „ Porozumění Správci virtuální paměti Linux “ je trochu zastaralá, ale souhlasí s tím, že se jedná o pomalou operaci:

Funkce odpovědná za deaktivaci oblasti se, dostatečně předvídatelně, nazývá sys_swapoff(). Tato funkce se týká hlavně aktualizace swap_info_struct. Hlavním úkolem stránkování na každé stránkované stránce je zodpovědnost try_to_unuse() což je extrémně drahé.

Od roku 2007 je o mailing listu linux-kernel trochu více diskuse s tématem " zrychlení swapoff " - ačkoliv rychlosti, o kterých diskutují, jsou o něco vyšší, než to, co vidíte.


Je to zajímavá otázka, která se pravděpodobně obecně ignoruje, protože swapoff se používá zřídka. Myslím, že pokud byste to opravdu chtěli sledovat, prvním krokem by bylo pokusit se pečlivě sledovat vzorce využití disku (možná pomocí atop, iostat nebo ještě výkonnějšími nástroji, jako je perf nebo systemtap). Věci, které je třeba hledat, mohou být nadměrné vyhledávání, malé I/O operace, neustálé přepisování a pohyb dat atd.

58
Jim Paris

Měl jsem stejný problém s mým notebookem, který má SSD, takže hledá časy by neměl být problém.

Našel jsem alternativní vysvětlení . Zde je výňatek

Jak to nyní funguje, swapoff se dívá na každou stránku s odloženou pamětí v odkládací oblasti a pokouší se najít všechny programy, které ji používají. Pokud je nenajde hned, vyhledá je v tabulkách stránek každého spuštěného programu. V nejhorším případě zkontroluje všechny tabulky stránek pro každou zaměněnou stránku v oddílu. To je pravda - stejné tabulky stránek se znovu a znovu kontrolují.

Jedná se tedy spíše o problém jádra než o nic jiného.

37
Nick Craig-Wood

Jo, mechanismus swapoff je hrozně neefektivní. Řešení je snadné: iteruje přes procesy, místo toho iteruje přes zaměněné stránky. Použijte tento skript python (nejsem přidružený):

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

Provozní režim démona je určen pouze pro stolní počítače/notebooky, které jsou často hibernace. Nechtěl bych to spustit jako démona na serverovém systému - stačí ho spustit v popředí, počkat, až ohlásí, že se postaral o některé procesy, pak to zastavit a zkusit:

swapoff /dev/x

Protože většina stránek je nyní přítomna jak ve swapu, tak i v paměti, swapoff nemá co dělat a mělo by být nyní nesmírně rychlé (viděl jsem stovky MB/s).

Historie sekce dopředu

Výše uvedený skript python) je založen na zbytku této odpovědi, což na oplátku bylo mým vylepšením tato starší odpověď autorem jlong. Protože je skript mnohem bezpečnější, doporučuji vyzkoušet pouze zbytek mé odpovědi jako poslední obrannou linii :

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

To běží asi 2 sekundy a ve skutečnosti nic neuděláte, stačí uvést seznam 10 hlavních segmentů paměti (ve skutečnosti se vytiskne více jednořadých linií; ano I do miluji jednoplášťové; jen prozkoumejte příkazy, přijměte riziko, zkopírujte a vložte do své schránky; tyto budou skutečně načteny ze swapu).

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

Hlavní jednoplášťová loď je bezpečná (pro mě), kromě toho, že čte hodně/proc.

Dílčí příkazy připravené pro vaše ruční vyšetření nejsou bezpečné . Každý příkaz zavěsí jeden proces po dobu čtení segmentu paměti ze swapu. Takže to není bezpečné s procesy, které netolerují žádné pauzy. Rychlosti přenosu, které jsem viděl, byly řádově 1 gigabajt za minutu. (Výše uvedený nedostatek python tento nedostatek odstranil).

Dalším nebezpečím je příliš velký tlak v paměti na systém, proto se obraťte na obvyklý free -m

Co to dělá?

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" 
        }
      }
    }
  }
}

Výstupem tohoto skriptu Perl je řada gdb příkazů dump memory (range), které vyvolávají zaměněné stránky do paměti.

Výstup začíná velikostí, takže je dost snadné jej projít skrz | sort -Vr | head A získat 10 největších segmentů podle velikosti (SSIZE). -V Znamená třídění podle čísla verze, ale funguje to pro můj účel. Nemohl jsem přijít na to, jak zajistit numerické řazení.

23
kubanczyk

Pokud během výměny dojde k detekci používaného výměnného slotu, jádro se nejprve zamění na stránce. Funkce unuse_process () se poté pokusí najít všechny položky tabulky stránek, které odpovídají právě zaměněné stránce, a provede nezbytnou aktualizaci tabulek stránek. Hledání je vyčerpávající a časově náročné: navštěvuje každý deskriptor paměti (celého systému) a jednotlivé položky tabulky stránek prozkoumává jeden po druhém.

Viz strana 724 v části „Porozumění verzi 3. jádra systému Linux“.

11
Leslie