Gibt es eine Methode, um den Kopiervorgang unter Linux zu verlangsamen?
Ich habe eine große Datei, sagen wir 10 GB, und ich möchte sie in ein anderes Verzeichnis kopieren, aber ich möchte sie nicht mit voller Geschwindigkeit kopieren. Nehmen wir an, ich möchte es mit einer Geschwindigkeit von 1 MB / s kopieren, nicht schneller. Ich möchte einen Standard-Linux- cp
Befehl verwenden.
Ist das möglich? (Wenn ja, wie?)
Bearbeiten : Also werde ich mehr Kontext zu dem hinzufügen, was ich erreichen will.
Ich habe ein Problem mit dem ArchLinux-System beim Kopieren großer Dateien über USB (auf ein USB-Laufwerk, eine USB-Festplatte usw.). Nach dem Auffüllen des USB-Pufferspeichers reagiert mein System nicht mehr (selbst die Maus bleibt stehen; sie bewegt sich nur sporadisch). Der Kopiervorgang ist noch nicht abgeschlossen, beansprucht jedoch 100% der Box. Wenn der Kopiervorgang abgeschlossen ist, kehrt alles zum Normalzustand zurück - alles reagiert wieder perfekt.
Vielleicht ist es ein Hardwarefehler, ich weiß es nicht, aber ich weiß, ich habe zwei Computer mit diesem Problem (beide sind unter ArchLinux, einer ist eine Desktop-Box, der zweite ist ein Laptop).
Die einfachste und schnellste "Lösung" für dieses Problem (ich stimme zu, es ist nicht die "echte" Lösung, sondern nur ein hässlicher "Hack") besteht darin, zu verhindern, dass dieser Puffer voll wird, indem die Datei mit einer durchschnittlichen Schreibgeschwindigkeit des USB - Laufwerks kopiert wird, z mir wäre das genug
quelle
ionice
kann verwendet werden , um sicherzustellen , dass Ihr Disk-to-Disk - Kopiervorgang geplant ist I / O mit einer niedrigeren Priorität als normale Prozesse.cat file | pv -L 3k > outfile
. Beides ist jedoch nicht dasselbe wie die Verwendung von cp (1).Antworten:
Sie können eine Pipe mit
pv -qL
(oder einercstream -t
ähnlichen Funktion) drosseln.-q
Entfernt stderr Fortschrittsberichte.Das
-L
Limit ist in Bytes.Mehr über die
--rate-limit/-L
Flagge von derman pv
:Diese Antwort wies ursprünglich darauf hin,
throttle
aber dieses Projekt ist nicht mehr verfügbar und ist aus einigen Paketsystemen herausgerutscht.quelle
cp
dies nicht verlangsamt werden kann, ist die Verwendung eines benutzerdefinierten Befehls die einzige Option, die ich denke.rsync
pv
. Vielen Dank.Stattdessen
cp -a /foo /bar
können Siersync
die Bandbreite auch nach Bedarf nutzen und begrenzen.Aus dem
rsync
Handbuch:Der aktuelle Befehl, der auch den Fortschritt anzeigt, würde also so aussehen:
quelle
/dev/zero
oder/dev/random
rsync -a --bwlimit=1500 /source /destination
Funktioniert perfekt, um riesige Ordner mit einer Geschwindigkeit von 1,5 MB / s zu kopieren (was ein guter Kompromiss zwischen der Vermeidung von Server-Verlangsamungen und einem geringen Zeitaufwand ist)20m
wird sie beispielsweise nicht auf allen Plattformen unterstützt. Halten Sie sich daher besser an die KByte-Notation.cgexec -g ... cp /in /out
nicht die ganze Zeit gearbeitet (vom Terminal hat manchmal gearbeitet, vom Skript nie) und ich habe keine Ahnung warum ...Ich würde annehmen, dass Sie versuchen, andere Aktivitäten nicht zu stören. Neuere Linux-Versionen enthalten Funktionen, mit
ionice
denen Sie die Planung von E / A steuern können.Neben dem Zulassen verschiedener Prioritäten gibt es eine zusätzliche Option, um die E / A auf Zeiten zu beschränken, in denen sich die Festplatte ansonsten im Leerlauf befindet. Der Befehl
man ionice
zeigt die Dokumentation an.Versuchen Sie, die Datei mit einem Befehl wie dem folgenden zu kopieren:
Wenn sich die beiden Verzeichnisse auf demselben Gerät befinden, können Sie feststellen, dass das Verknüpfen der Datei die gewünschten Aktionen ausführt. Wenn Sie zu Sicherungszwecken kopieren, verwenden Sie diese Option nicht.
ln
ist extrem schnell, da die Datei selbst nicht kopiert wird. Versuchen:Oder wenn Sie nur von einem Verzeichnis auf einem anderen Gerät darauf zugreifen möchten, versuchen Sie Folgendes:
quelle
Wenn die
ionice
Lösung nicht ausreicht (warum auch immer) und Sie I / O wirklich auf einen absoluten Wert beschränken möchten, gibt es mehrere Möglichkeiten:die wahrscheinlich einfachste:
ssh
. Es gibt ein eingebautes Bandbreitenlimit. Sie würden zBtar
(anstelle voncp
) oderscp
(wenn das gut genug ist; ich weiß nicht, wie es mit Symlinks und Hardlinks umgeht) oder verwendenrsync
. Diese Befehle können ihre Daten weiterleitenssh
. Wenntar
Sie schreiben/dev/stdout
(oder-
),ssh
leiten Sie diestar
an den Client weiter, der einen anderen auf der "entfernten" Seite ausführt .Elegant, aber nicht im Vanillekern (AFAIK): Das Device-Mapper-Ziel
ioband
. Dies funktioniert natürlich nur, wenn Sie entweder das Quell- oder das Ziel-Volume ummounten können.Selbstgeschriebener Spaß:
grep "^write_bytes: " /proc/$PID/io
Gibt die Datenmenge an, die ein Prozess geschrieben hat. Sie könnten ein Skript schreiben, dascp
im Hintergrund startet , z. B. eine Zehntelsekunde ruht, den Hintergrundprozess stopptcp
(kill -STOP $PID
), den geschriebenen Betrag prüft (und in diesem Fall ungefähr den gleichen Wert liest) und berechnet, wie lange er dauertcp
muss pausieren, um die durchschnittliche Übertragungsrate auf den beabsichtigten Wert zu senken, für diese Zeit schläft, aufwachtcp
(kill -CONT $PID
) und so weiter.quelle
Ihr Problem liegt wahrscheinlich nicht an Ihrem Computer, an sich ist es wahrscheinlich in Ordnung. Aber diese USB-Flash-Übergangsschicht hat einen eigenen Prozessor, der all Ihre Schreibvorgänge abbildet, um so viel wie einen zu 90% fehlerhaften Flash-Chip zu kompensieren, wer weiß? Sie überfluten es, dann überfluten Sie Ihre Puffer, dann überfluten Sie den gesamten Bus, dann stecken Sie fest, Mann - schließlich sind alle Ihre Sachen dort. Es klingt vielleicht kontraintuitiv, aber was Sie wirklich brauchen, ist die Blockierung von E / A - Sie müssen die FTL das Tempo bestimmen lassen und dann einfach mithalten.
(Zum Hacken von FTL-Mikrocontrollern: http://www.bunniestudios.com/blog/?p=3554 )
Alle obigen Antworten sollten funktionieren, also ist dies eher ein "Ich auch!" als alles andere: Ich war total da, Mann. Ich habe meine eigenen Probleme mit rsyncs --bwlimit arg gelöst (2,5 MB schienen der Sweet Spot für einen einzigen fehlerfreien Durchlauf zu sein - alles andere und ich würde mit Schreibschutzfehlern enden). rsync war für meinen Zweck besonders geeignet, da ich mit ganzen Dateisystemen arbeitete - es gab also viele Dateien - und einfach ein zweites Mal rsync ausführen konnte, um alle Probleme des ersten Laufs zu beheben (was notwendig war, wenn ich ungeduldig wurde und es versuchte) an 2.5mbs vorbeifahren).
Trotzdem denke ich, dass das für eine einzelne Datei nicht ganz so praktisch ist. In Ihrem Fall können Sie einfach per Pipe zu dd set auf raw-write setzen - Sie können jede Eingabe auf diese Weise verarbeiten, aber nur jeweils eine Zieldatei (obwohl diese einzelne Datei natürlich ein ganzes Blockgerät sein kann).
Sie könnten feststellen, dass Netcat beim Datentransport etwas schneller ist als SSH, wenn Sie es ausprobieren. Wie auch immer, die anderen Ideen wurden bereits aufgenommen, warum also nicht?
[BEARBEITEN]: Ich habe die Erwähnungen von lftp, scp und ssh in dem anderen Beitrag bemerkt und dachte, wir sprechen über eine Remote-Kopie. Local ist viel einfacher:
[EDIT2]: Gutschrift, wo es fällig ist: Ich habe gerade bemerkt, dass mich ptman in den Kommentaren um etwa fünf Stunden geschlagen hat.
Auf jeden Fall könnten Sie $ bs mit einem Multiplikator auf Leistung einstellen. Bei einigen Dateisystemen muss es jedoch ein Vielfaches der Sektorgröße des Ziel-fs sein. Denken Sie also daran.
quelle
--getioopt
nicht--getoptio
Das Problem ist, dass die Kopie Ihren Speicher mit Blöcken "im Flug" füllt und "nützliche" Daten verdrängt. Ein bekannter (und sehr schwer zu behebender) Fehler in der Linux-Kernel-Verarbeitung von E / A, um Geräte zu verlangsamen (in diesem Fall USB).
Vielleicht können Sie versuchen, das Kopieren zu parzellieren, z. B. durch ein Skript wie das folgende (Proof-of-Concept-Skizze, völlig ungetestet!):
Anpassen
seek
undskip
voncount
jeder Runde. Es muss abgestimmt werden,count
damit nicht zu viel Speicherplatz belegt wird und der Speicher5
entleert wird.quelle
Senken Sie das Limit für verschmutzte Seiten. Das Standardlimit ist Wahnsinn.
Erstellen Sie /etc/sysctl.d/99-sysctl.conf mit:
Führen Sie dann sysctl -p aus oder starten Sie neu.
Was passiert, ist, dass Daten schneller gelesen werden, als sie auf den Zieldatenträger geschrieben werden können. Wenn Linux Dateien kopiert, werden diese in den RAM eingelesen und die Seiten zum Schreiben an das Ziel als verschmutzt markiert. Verschmutzte Seiten können nicht ausgetauscht werden. Wenn der Quelldatenträger schneller als der Zieldatenträger ist und Sie mehr Daten kopieren, als über freien Arbeitsspeicher verfügen, wird durch den Kopiervorgang der gesamte verfügbare Arbeitsspeicher (oder zumindest die Obergrenze für fehlerhafte Seiten, die möglicherweise über der Obergrenze liegt) aufgebraucht verfügbarer RAM) und Hunger verursachen, da die verschmutzten Seiten nicht ausgetauscht werden können und saubere Seiten verwendet und als verschmutzt markiert werden, wenn sie freigegeben werden.
Beachten Sie, dass dies das Problem nicht vollständig lösen wird. Was Linux wirklich benötigt, ist eine Möglichkeit, die Erstellung schmutziger Seiten zu arbitrieren, sodass eine große Übertragung nicht den gesamten verfügbaren Arbeitsspeicher / alle zulässigen schmutzigen Seiten verschlingt.
quelle
Dieses Problem hat nichts mit Fehlern oder Fehlern in der Hardware oder Software zu tun. Es ist nur Ihr Kernel, der versucht, nett zu Ihnen zu sein und Ihre Aufforderung zurückzugeben und im Hintergrund zu kopieren (es verwendet einen kerninternen Cache: mehr RAM, mehr Cache, Sie können dies jedoch einschränken, indem Sie irgendwo in / proc schreiben (dies wird jedoch nicht empfohlen). Flash-Laufwerke sind zu langsam, und während der Kernel darauf schreibt, können andere E / A-Vorgänge nicht schnell genug ausgeführt werden.
ionice
mehrmals in anderen antworten erwähnt ist ok. Aber haben Sie versucht, nur das Laufwerk mit-o sync
zu mounten, um eine Pufferung des Betriebssystems zu vermeiden? Es ist wahrscheinlich die einfachste Lösung da draußen.quelle