Parallele Dateikopie


9

Ich habe eine Liste von Dateien, die ich auf einem Linux-System kopieren muss - jede Datei hat eine Größe von 10 bis 100 GB.

Ich möchte nur in das lokale Dateisystem kopieren. Gibt es eine Möglichkeit, dies auf einfache Weise parallel zu tun - mit mehreren Prozessen, die jeweils für das Kopieren einer Datei verantwortlich sind?

Ich kann leicht ein Multithread-Programm schreiben, um dies zu tun, aber ich bin daran interessiert herauszufinden, ob es eine Low-Level-Linux-Methode dafür gibt.


1
Das parallele Kopieren von Dateien beschleunigt nicht wesentlich. (Zumindest theoretisch sollte es nicht.)
Tarnay Kálmán


1
@ TarnayKálmán, es sei denn, Sie haben ein Clustered-, Overlay-, RAID- oder "Unraid" -Dateisystem oder eines der oben genannten über eine relativ hohe Latenz oder ein ausgelastetes Netzwerk. oder eine Arbeitslast, bei der die Latenz pro Datei einen wesentlichen Teil der Kopierzeit für diese Datei ausmacht (1e5 + sehr kleine Dateien, inhaltsadressierte Backends usw.). Die gleichzeitige Verarbeitung wäre in solchen Situationen äußerst nützlich.
Wert

Antworten:


11

Wenn Ihr System nicht davon betroffen ist (z. B. befinden sich die Dateien möglicherweise im Cache), funktioniert GNU Parallel http://www.gnu.org/software/parallel/ möglicherweise für Sie:

find . -print0 | parallel -0 -j10 cp {} destdir

Dies führt 10 gleichzeitige cps aus.

Pro: Es ist einfach zu lesen.

Con: GNU Parallel ist auf den meisten Systemen nicht Standard - daher müssen Sie es wahrscheinlich installieren.

Weitere Informationen finden Sie im Intro-Video: http://www.youtube.com/watch?v=OpaiGYxkSuQ

Siehe auch https://oletange.wordpress.com/2015/07/04/parallel-disk-io-is-it-faster/ für eine Erläuterung der parallelen Festplatten-E / A.


3

Es gibt aus einem sehr einfachen Grund keinen einfachen Mechanismus dafür: Wenn Sie dies tun, wird Ihre Systemleistung zerstört. Bei Plattentellerlaufwerken kämpft jeder Schreibvorgang um die Platzierung des Kopfes, was zu einer massiven E / A-Wartezeit führt. Bei SSDs wird dadurch einer oder mehrere Ihrer Systembusse gesättigt, was zu anderen Problemen führt.


Ähm, das scheint derzeit bei einem einzelnen CP nicht der Fall zu sein. Ich bin sicher, es gibt ein glückliches Medium für mehrere parallele "CPs", bei denen Ihr E / A-Kanal nicht vollständig gesättigt ist ...
Jon

1
Ein gesättigter Bus ist ein fröhlicher Bus. Leerlaufbandbreite ist verschwendete Bandbreite.
Wert

3

Wie bereits erwähnt, ist dies eine schreckliche Idee. Aber ich glaube, jeder sollte in der Lage sein, seine eigenen schrecklichen Pläne umzusetzen, sooo ...

for FILE in *;do cp $FILE <destination> &;done

Das Sternchen kann durch einen regulären Ausdruck Ihrer Dateien ersetzt werden oder $(cat <listfile>)wenn Sie alle in einem Textdokument haben. Das kaufmännische Und startet einen Befehl im Hintergrund, sodass die Schleife fortgesetzt wird und weitere Kopien erzeugt werden.

Wie bereits erwähnt, wird dies Ihre E / A vollständig vernichten. Also ... ich würde es wirklich nicht empfehlen.

- Christ Karel


3

Die einzige Antwort, die die Reaktionsfähigkeit Ihres Computers nicht beeinträchtigt, ist nicht gerade eine "Kopie", aber sie ist sehr schnell. Wenn Sie die Dateien nicht am neuen oder alten Speicherort bearbeiten, ähnelt ein fester Link praktisch einer Kopie, und (nur) wenn Sie sich im selben Dateisystem befinden, werden sie sehr, sehr schnell erstellt.

Überprüfen Sie, cp -lob es für Sie funktioniert.


2

Hier ist ein verteiltes / paralleles und dezentrales Tool zum Kopieren von Dateien, das die Datei aufteilt und alle Teile parallel kopiert. Es wird Ihnen wahrscheinlich nur helfen, wenn Sie eine SSD haben, die mehrere Streams oder eine Art Setup mit mehreren Plattenköpfen unterstützt.

https://github.com/hpc/dcp


1

Für die Leute, die denken, dass das keine großartige Idee ist, würde ich sagen, dass es davon abhängt. Sie können ein großes RAID-System oder ein paralleles Dateisystem haben, das eine wirklich bessere Leistung liefert, als ein CP-Prozess verarbeiten kann. Dann müssen Sie ja ein "paralleles Werkzeug" verwenden.

Nehmen wir dieses Beispiel:

timeout 10 strace -e write -c cp /dev/zero /dev/null
strace: Process 24187 detached
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
100.00    0.655188           4    166222           write
------ ----------- ----------- --------- --------- ----------------
100.00    0.655188                166222           total

dann das

timeout 0.01 strace -e write  cp /dev/zero /dev/null
write(4, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 65536) = 65536
write(4, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 65536) = 65536
write(4, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 65536) = 65536
write(4, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 65536) = 65536
write(4, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 65536) = 65536
write(4, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 65536) = 65536
write(4, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 65536) = 65536
strace: Process 24567 detached

Daher ist jeder von "cp" in diesem Fall erstellte Syscall-Schreibvorgang 64 KB und für 10 Sekunden auf meinem System kann ich diese Bandbreite bereitstellen: 65536 * 166222/10 = 1089352499 = ~ 1,08 GB / s

Lassen Sie uns nun diese Workload mit 2 Prozessen starten (ich habe 4 Kerne, aber mein Desktop wird für andere Dinge verwendet, und hier ist es nur ein Beispiel):

timeout 10 strace -e write -c cp /dev/zero /dev/null & timeout 10 strace -e write -c cp /dev/zero /dev/null &  wait
[1] 26106
[2] 26107
strace: Process 26113 detached
strace: Process 26112 detached
% time     seconds  usecs/call     calls    errors syscall
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
------ ----------- ----------- --------- --------- ----------------
100.00    0.624108           4    162616           write
100.00    0.638468           4    162451           write
------ ----------- ----------- --------- --------- ----------------
100.00    0.624108                162616           total
100.00    0.638468                162451           total
------ ----------- ----------- --------- --------- ----------------
[1]-  Exit 124                timeout 10 strace -e write -c cp /dev/zero /dev/null

Wir sehen also, dass wir die Leistung mit 2 Kernen nahezu verdoppeln können, um dies zu starten.

Wenn wir uns also in einem anderen Kontext als 1xHard-Laufwerk von 1xHard-Laufwerk befinden, aber ein RAID-Array (oder mehrere NVMe, also nicht der häufigste Fall, dem ich zustimme, aber ich arbeite jeden Tag daran), zeigt es definitiv eine bessere Leistung, mehrere Common-In-Laufwerke zu verwenden parallel.


-1

Sie sollten dies versuchen:

    $ seq 3 | parallel cp -v / etc / passwd passwd {}

Dadurch wird die Datei passwd dreimal aus dem Verzeichnis / etc / in Ihr $ HOME kopiert

Oder wenn sich Ihre Datei in Ihrem Home-Verzeichnis befindet

    $ seq 3 | parallel cp -v passwd {, {}}

Dadurch wird die Datei passwd dreimal in Ihr $ HOME kopiert

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.