Jak swapoff może być tak wolny?


77

Jakoś zdarzyło mi się wymienić 14 GB pamięci. Po zabiciu sprawcy znów mam mnóstwo wolnej pamięci, więc pomyślałem, że mogę ponownie wprowadzić ważne dane . Tak więc przy 5 GB z 32 GB i 14 GB miejsca do wymiany, pobiegłem swapoff -a.... i 4 godziny później około połowa pracy została zakończona.

Oznacza to mniej niż 1 MB / s, podczas gdy mogę łatwo skopiować 200 MB / s. Moja zamiana jest zaszyfrowana, ale podobnie jak wszystkie normalne partycje, a aes-ni nie powoduje zauważalnego obciążenia procesora (a wypełnienie przestrzeni wymiany zajęło tylko kilka minut). Widzę, że nie ma specjalnego powodu do optymalizacji swapoff, ale zastanawiam się, w jaki sposób można to zrobić tak wolno?


Po prostu dodaję trochę więcej danych: Moja główna pamięć to 32 GB i mam 32 GB przestrzeni wymiany na każdym z 4 dysków twardych (na pewno przesada, ale kogo to obchodzi?). Całą przestrzeń wymiany można (odszyfrować i) odczytać w mniej niż 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

Czytanie części partycji nie może być wolniejsze niż czytanie wszystkich. Jednak odczyt około 1/10 tego zajmuje około 100 razy dłużej.

Zauważyłem, że podczas swapoffobu procesor był w większości bezczynny (może 10% jednego rdzenia), podobnie jak dyski („mierzone” przez diody LED). Widziałem także, że przestrzenie wymiany zostały wyłączone jeden po drugim.


1
Zastanawiam się, czy to samo zjawisko występuje, gdy system sam ładuje zamienione strony z powrotem do pamięci RAM? Na przykład, jeśli system został zawieszony na dysku, a następnie uruchomiony, wszystko zostało zamienione i jest ładowane z powrotem do pamięci RAM. Wydaje mi się też, że jest bardzo powolny.
Petr Pudlák,

Czy wszystkie urządzenia wymienne są aktywowane z tym samym priorytetem?
Nils

@Petr Pudlák: Zawieszenie na dysk jest nieco inne, po prostu zapisuje zawartość pamięci RAM w wolnym miejscu w obszarze wymiany, a to (i cofanie zawieszenia) jest prawdopodobnie znacznie szybsze. Nie mogę spróbować, ponieważ nie działa w przypadku szyfrowanej wymiany.
maaartinus

@Nils: Tak, priorytet jest taki sam, podobnie jak dysk i ich partycjonowanie.
maaartinus,

To czyni to bardziej dziwnym. W tym przypadku zamiana jest rozłożona na wszystkich dyskach - powinno to być bardzo szybkie. Czy iostat -d 5w tym czasie swapoffrównież pokazywał niskie IO na dyskach ?
Nils,

Odpowiedzi:


53

Najpierw przyjrzyjmy się, czego możesz oczekiwać od dysku twardego. Twój dysk twardy może osiągać prędkość 200 MB / s sekwencyjnie . Jeśli weźmiesz pod uwagę czas wyszukiwania, może być znacznie wolniejszy. Aby wybrać dowolny przykład, zapoznaj się ze specyfikacją jednego z nowoczesnych dysków 3 TB Seagate, ST3000DM001 :

  • Maksymalna trwała szybkość przesyłania danych: 210 MB / s

  • Szukaj średniej odczytu: <8,5 ms

  • Bajtów na sektor: 4096

Jeśli nigdy nie musisz szukać, a twoja zamiana znajduje się blisko krawędzi dysku, możesz spodziewać się maksymalnej prędkości = 210 MB / s

Ale jeśli dane wymiany są całkowicie fragmentaryczne, w najgorszym przypadku będziesz musiał poszukać każdego czytanego sektora. Oznacza to, że możesz odczytać tylko 4 KB co 8,5 ms lub 4 KB / 0,0085 = 470 KB / s

Od razu więc nietoperz nie jest nie do pomyślenia , że faktycznie spotykasz się z prędkością dysku twardego.


To powiedziawszy, wydaje się głupie, swapoffże działałoby tak wolno i musiałoby czytać strony w porządku, zwłaszcza jeśli zostały napisane szybko (co oznacza uporządkowanie). Ale może tak po prostu działa jądro. Raport o błędach Ubuntu # 486666 omawia ten sam problem:

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

Jedną z odpowiedzi było:

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

Raport o błędzie został zamknięty nierozwiązany.

Książka Mela Gormana „ Understanding the Linux Virtual Memory Manager ” jest nieco nieaktualna, ale zgadza się, że jest to powolna operacja:

Funkcja odpowiedzialna za dezaktywację obszaru jest, jak można przewidzieć, wywoływana sys_swapoff(). Ta funkcja dotyczy głównie aktualizacji swap_info_struct. Głównym zadaniem stronicowania na każdej stronie stronicowanej try_to_unuse()jest niezwykle kosztowna odpowiedzialność.

Od 2007 roku jest nieco więcej dyskusji na temat listy mailingowej jądra Linux-a na temat „ przyspieszenie swapoff ” - chociaż prędkości, o których dyskutują, są nieco wyższe niż to, co widzisz.


To interesujące pytanie, które prawdopodobnie jest na ogół ignorowane, ponieważ swapoffjest rzadko używane. Myślę, że jeśli naprawdę chce śledzić ją w dół, pierwszym krokiem będzie próbował obserwować swoje wzorce użycia dysku bardziej ostrożnie (może z atop, iostatlub nawet bardziej skuteczne narzędzia jak perflub systemtap). Rzeczy, których należy szukać, to nadmierne wyszukiwanie, małe operacje we / wy, ciągłe przepisywanie i przenoszenie danych itp.


5
Doskonałe wyjaśnienie. Należy zauważyć, że możliwe jest obejście większości fragmentacji i szybkie zwolnienie większości swapów poprzez zrzutowanie
Brandon DuPree

To nie tylko fragmentacja / czas poszukiwań. Moja zamiana jest na dysku SSD, a losowe odczyty są bardzo szybkie, ale polecenie zamiany jest znacznie wolniejsze niż powinno, a obciążenie dysku SSD wynosi około 1%. Podejrzewam, że gdzieś w jądrze lub swapoffie chodzi o chodzenie po listach (które wykorzystuje ~ 90-100% procesora). Oczywiście, jeśli cała praca jest wykonywana sekwencyjnie, a wyszukiwanie dysku jest zbyt wolne, może się znacznie zsumować.
Thomas Guyot-Sionnest

33

Mam ten sam problem z laptopem, który ma dysk SSD, więc szukanie czasu nie powinno stanowić problemu.

Znalazłem alternatywne wyjaśnienie . Oto fragment

Sposób, w jaki teraz działa, swapoff patrzy na każdą wymienioną stronę pamięci na partycji wymiany i próbuje znaleźć wszystkie programy, które z niej korzystają. Jeśli nie może ich znaleźć od razu, przejrzy tabele stron każdego uruchomionego programu, aby je znaleźć. W najgorszym przypadku sprawdzi wszystkie tabele stron dla każdej zamienionej strony w partycji. Zgadza się - te same tabele stron są sprawdzane w kółko.

Jest to więc problem jądra, a nie cokolwiek innego.


Nie, to nie jest problem z jądrem IMHO. Tak to swapoffjest realizowane. Po zakończeniu procesu zamiany nie trwa to długo.
Marki555

15
Jest to problem z implementacją zamiany, która znajduje się w jądrze - stąd problem z jądrem! Możesz zobaczyć, czy strace swapoffwłaściwie wszystko, co robi, to wywoływanie połączenia swapoffsystemowego.
Nick Craig-Wood

1
Mam serwer z 48 GB pamięci RAM (32 rdzeni), miałem 6 GB bezpłatnej wymiany błędów, użyto 0,7 GB. swappiness = 10, próbował uzyskać wartość 0, a także próbował swapoff, aby zobaczyć, co się stanie. swapoff trwa wieki, prawdopodobnie 30 minut, uwalniając swap bardzo wolno. Mam dysk SSD prawie bez obciążenia, a procesor jest podobny, spodziewaj się procesu zamiany, który wymaga jednego procesora 100%.
sorin

1
Problem polega na tym, w jaki sposób swapoff jest implementowany (w jądrze). Kilka lat temu dyskutowano o znacznie lepszym podejściu do kernel-dev, ale mówią, że jest to przypadek narożny i nie chcą wysiłku, aby to zmienić.
Marki555

6
Na serwerze z 1 TB RAM (tak, TB) i 2 GB swap (głupie wymaganie SAP) wymiana zajęła 12 godzin, aby uwolnić 5% z tych 2 GB (z 1 rdzeniem procesora na 100%).
Marki555

22

Tak, swapoffmechanizm jest strasznie nieefektywny. Obejście tego problemu jest łatwe: iteracja procesów, zamiast iteracji po zamienionych stronach. Użyj tego skryptu python (nie jestem powiązany):

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

Należy pamiętać, że tryb działania demona dotyczy tylko komputerów stacjonarnych / laptopów, które często są hibernowane. Nie uruchomiłbym go jako demona w systemie serwera - wystarczy uruchomić go na pierwszym planie, poczekać, aż zgłosi, że zajął się niektórymi procesami, a następnie zatrzymać go i spróbować:

swapoff /dev/x

Ponieważ większość stron jest teraz obecna zarówno w trybie wymiany, jak i pamięci, swapoffma bardzo niewiele do zrobienia i powinna być teraz niesamowicie szybka (widziałem setki MB / s).

Sekcja historii przed nami

Wyżej wspomniany skrypt Pythona jest oparty na pozostałej części tej odpowiedzi, co z kolei było moją poprawą tej starszej odpowiedzi autorstwa Jlonga . Ponieważ skrypt jest znacznie bezpieczniejszy, polecam wypróbować resztę odpowiedzi jako ostatnią linię obrony :

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

Działa to może 2 sekundy i właściwie nic nie robi, po prostu wypisz 10 najlepszych segmentów pamięci (w rzeczywistości drukuje więcej jedno-liniowych; tak , uwielbiam jedno-liniowe; po prostu sprawdź polecenia, zaakceptuj ryzyko, skopiuj i wklej do twoją powłokę; będą one czytać z wymiany).

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

Główny jednowierszowy jest bezpieczny (dla mnie), tyle że czyta dużo / proc.

Polecenia podrzędne przygotowane do ręcznego sprawdzenia niebezpieczne . Każde polecenie zawiesi jeden proces na czas odczytu segmentu pamięci z wymiany. Jest to więc niebezpieczne w przypadku procesów, które nie tolerują żadnych przerw. Prędkości transferu, które widziałem, były rzędu 1 gigabajta na minutę. (Wspomniany skrypt Pythona usunął ten brak).

Innym niebezpieczeństwem jest zbyt duże obciążenie pamięci systemu, więc sprawdź to w zwykły sposób free -m

Co to robi?

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

Wynikiem tego skryptu perl jest seria gdbpoleceń, dump memory (range)które przywołują zamienione strony do pamięci.

Dane wyjściowe zaczynają się od rozmiaru, więc łatwo jest przejść przez nie, | sort -Vr | headaby uzyskać 10 największych segmentów według rozmiaru (SSIZE). W -Voznacza version-liczbowo nadaje sortowania, ale działa dla mojego celu. Nie mogłem wymyślić, jak sprawić, by sortowanie numeryczne działało.


sort -t = -k 2n
Użyłbyś

9
Wydaje się, że nie ma potrzeby używania gdb do podglądania pamięci procesu (przynajmniej w najnowszych jądrach). Można po prostu otwierać /proc/$pid/mem, wyszukiwać i czytać bezpośrednio. Oto PoC w dużej mierze oparty na twoim fragmencie: gist.github.com/WGH-/91260f6d65db88be2c847053c49be5ae W ten sposób proces nie jest zatrzymywany, AFAIK, nie powinno być z tego powodu żadnych zagrożeń.
WGH,

10

Jeśli podczas wymiany zostanie wykryty używany slot wymiany, jądro najpierw zamieni się na stronie. Funkcja unuse_process () następnie próbuje znaleźć wszystkie wpisy w tabeli stron, które odpowiadają właśnie zamienionej stronie i dokonuje koniecznej aktualizacji tabel stron. Wyszukiwanie jest wyczerpujące i bardzo czasochłonne: odwiedza każdy deskryptor pamięci (całego systemu) i sprawdza kolejno wpisy w tablicy stron.

Proszę odnieść się do strony 724 w „Understanding the Linux Kernel 3rd version”.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.