it-swarm.com.de

Wie kann Swapoff so langsam sein?

Irgendwie habe ich zufällig 14 GB Speicher ausgetauscht. Nachdem ich den Täter getötet habe, habe ich wieder jede Menge freien Speicher, also dachte ich, ich könnte wichtige Daten einbringen wieder. Mit 5 GB von 32 GB und 14 GB Swap-Speicher lief ich also swapoff -a.... und 4 Stunden später war ungefähr die Hälfte der Arbeit beendet.

Dies bedeutet weniger als 1 MB/s, während ich problemlos 200 MB/s kopieren kann. Mein Swap ist verschlüsselt, aber auch alle normalen Partitionen. Mit aes-ni führt dies zu keiner merklichen CPU-Auslastung (und das Ausfüllen des Swap-Bereichs dauerte nur wenige Minuten). Ich sehe, dass es keinen besonderen Grund gibt, swapoff zu optimieren, aber ich frage mich, wie es so langsam werden könnte?


Nur noch ein paar Daten hinzufügen: Mein Hauptspeicher ist 32 GB und ich habe 32 GB Swap-Speicherplatz auf jeder der 4 Festplatten (sicherlich ein Overkill, aber wen interessiert das?). Der gesamte Swap Space kann in weniger als 5 Minuten (entschlüsselt und) gelesen werden:

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

Das Lesen eines Teils einer Partition kann nicht langsamer sein als das Lesen aller Teile. Das Lesen von ungefähr 1/10 dauert jedoch ungefähr 100 Mal länger.

Ich beobachtete, dass während swapoff sowohl die CPU im Leerlauf war (vielleicht 10% eines Kerns) als auch die Festplatten (von den LEDs "gemessen"). Ich habe auch gesehen, dass die Swap Spaces nacheinander ausgeschaltet wurden.

82
maaartinus

Schauen wir uns zunächst an, was Sie von Ihrer Festplatte erwarten können. Ihre Festplatte kann 200 MB/s nacheinander. Wenn Sie Suchzeiten berücksichtigen, kann es viel langsamer sein. Um ein beliebiges Beispiel auszuwählen, werfen Sie einen Blick auf die technischen Daten einer der modernen 3-TB-Festplatten von Seagate, der ST3000DM001 :

  • Maximale Dauerdatenrate: 210 MB/s

  • Durchschnittliches Lesen suchen: <8,5 ms

  • Bytes pro Sektor: 4.096

Wenn Sie nie suchen müssen und sich Ihr Swap in der Nähe des Randes der Festplatte befindet, können Sie mit einer maximalen Rate von = 210 MB/s rechnen. -)

Wenn Ihre Swap-Daten jedoch vollständig fragmentiert sind, müssen Sie im schlimmsten Fall nach jedem Sektor suchen, den Sie lesen. Das bedeutet, dass Sie nur alle 8,5 ms 4 KB lesen können oder 4 KB/0,0085 = 470 KB/s

Auf Anhieb ist es also nicht unvorstellbar, dass Sie tatsächlich auf Festplattengeschwindigkeiten stoßen.


Trotzdem scheint es albern, dass swapoff so langsam läuft und Seiten nicht in der richtigen Reihenfolge lesen muss, insbesondere wenn sie schnell geschrieben wurden (was eine In-Reihenfolge impliziert). Aber vielleicht funktioniert der Kernel so. Ubuntu-Fehlerbericht # 486666 diskutiert das gleiche 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

Eine der Antworten war:

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

Der Fehlerbericht wurde ungelöst geschlossen.

Mel Gormans Buch " Verständnis des Linux Virtual Memory Managers " ist etwas veraltet, stimmt jedoch zu, dass dies eine langsame Operation ist:

Die Funktion, die für die Deaktivierung eines Bereichs verantwortlich ist, heißt vorhersehbar sys_swapoff(). Diese Funktion befasst sich hauptsächlich mit der Aktualisierung von swap_info_struct. Die Hauptaufgabe des Paging auf jeder ausgelagerten Seite liegt in der Verantwortung von try_to_unuse(), was extrem teuer ist.

Ab 2007 gibt es ein bisschen mehr Diskussionen über die Linux-Kernel-Mailingliste mit dem Betreff " Beschleunigung des Swapoffs " - obwohl die Geschwindigkeiten, über die sie dort diskutieren, etwas höher sind als die, die Sie sehen.


Es ist eine interessante Frage, die wahrscheinlich allgemein ignoriert wird, da swapoff selten verwendet wird. Ich denke, wenn Sie es wirklich aufspüren wollten, wäre der erste Schritt, Ihre Festplattennutzungsmuster genauer zu beobachten (möglicherweise mit atop, iostat oder noch leistungsstärkeren Tools wie perf oder systemtap). Zu suchende Dinge können übermäßiges Suchen, kleine E/A-Vorgänge, ständiges Umschreiben und Verschieben von Daten usw. sein.

58
Jim Paris

Ich habe das gleiche Problem mit meinem Laptop, der eine SSD hat, so dass Suchzeiten kein Problem sein sollten.

Ich fand eine alternative Erklärung . Hier ist ein Auszug

So wie es jetzt funktioniert, betrachtet swapoff jede ausgelagerte Speicherseite in der Swap-Partition und versucht, alle Programme zu finden, die sie verwenden. Wenn sie nicht sofort gefunden werden können, werden die Seitentabellen aller laufenden Programme angezeigt, um sie zu finden. Im schlimmsten Fall werden alle Seitentabellen für jede ausgelagerte Seite in der Partition überprüft. Das ist richtig - die gleichen Seitentabellen werden immer wieder überprüft.

Es ist also eher ein Kernelproblem als irgendetwas anderes.

37
Nick Craig-Wood

Ja, der swapoff Mechanismus ist schrecklich ineffizient. Die Problemumgehung ist einfach: Durchlaufen Sie Prozesse und stattdessen die ausgetauschten Seiten. Verwenden Sie dieses python Skript (ich bin nicht verbunden):

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

Beachten Sie, dass der Daemon-Betriebsmodus nur für Desktops/Laptops gilt, die häufig im Ruhezustand sind. Ich würde es nicht als Daemon auf einem Serversystem ausführen - führen Sie es einfach im Vordergrund aus, warten Sie, bis es meldet, dass einige Prozesse erledigt wurden, und stoppen Sie es dann und versuchen Sie:

swapoff /dev/x

Da die meisten Seiten jetzt sowohl im Swap als auch im Speicher vorhanden sind, hat das swapoff sehr wenig zu tun und sollte jetzt blitzschnell sein (ich habe Hunderte von MB/s gesehen).

Geschichtsabschnitt voraus

Das oben erwähnte python Skript basiert auf dem Rest dieser Antwort, was wiederum meine Verbesserung von diese ältere Antwort war, die von verfasst wurde. jlong. Da das Skript viel sicherer ist, empfehle ich , nur den Rest meiner Antwort als letzte Verteidigungslinie zu versuchen :

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

Dies dauert vielleicht 2 Sekunden und führt eigentlich nichts aus. Listen Sie einfach die Top-10-Speichersegmente auf (tatsächlich werden mehr Einzeiler gedruckt; ja, ich mache liebe Einzeiler; Untersuchen Sie einfach die Befehle, akzeptieren Sie das Risiko, kopieren Sie sie und fügen Sie sie in Ihre Shell ein. diese werden tatsächlich aus dem Tausch gelesen).

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

Der Haupt-Einzeiler ist sicher (für mich), außer dass er viel/proc liest.

Die für Ihre manuelle Prüfung vorbereiteten Unterbefehle sind nicht sicher . Jeder Befehl hängt einen Prozess für die Dauer des Lesens eines Speichersegments aus dem Swap auf. Daher ist es bei Prozessen, die keine Pausen tolerieren, unsicher. Die Übertragungsgeschwindigkeiten, die ich sah, lagen in der Größenordnung von 1 Gigabyte pro Minute. (Das oben erwähnte python Skript hat diesen Mangel behoben).

Eine weitere Gefahr besteht darin, zu viel Speicherdruck auf das System auszuüben. Überprüfen Sie dies daher mit dem üblichen free -m

Was tut es?

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

Die Ausgabe dieses Perl-Skripts ist eine Reihe von gdb Befehlen dump memory (range), die ausgelagerte Seiten in den Speicher zurückrufen.

Die Ausgabe beginnt mit der Größe, daher ist es einfach genug, sie durch | sort -Vr | head Zu übergeben, um die 10 größten Segmente nach Größe (SSIZE) zu erhalten. Das -V Steht für eine für die Versionsnummer geeignete Sortierung, funktioniert aber für meinen Zweck. Ich konnte mir nicht vorstellen, wie man die numerische Sortierung zum Laufen bringt.

23
kubanczyk

Wenn beim Swapoff ein in Gebrauch befindlicher Swap-Slot erkannt wird, tauscht der Kernel zuerst auf der Seite. Die Funktion unuse_process () versucht dann, alle Seitentabelleneinträge zu finden, die der gerade eingetauschten Seite entsprechen, und führt die erforderlichen Aktualisierungen der Seitentabellen durch. Die Suche ist erschöpfend und sehr zeitaufwändig: Sie besucht jeden Speicherdeskriptor (des gesamten Systems) und überprüft die Seitentabelleneinträge nacheinander.

Weitere Informationen finden Sie auf Seite 724 unter "Grundlegendes zur 3. Version des Linux-Kernels".

11
Leslie