Was ist der beste Weg, um eine parallele Kopie unter Unix durchzuführen?

17

Ich muss regelmäßig den Inhalt eines Ordners in einem Netzwerkdateisystem auf meinen lokalen Computer kopieren. Es gibt viele Dateien (1000s) im Remote-Ordner, die alle relativ klein sind. Aufgrund des Netzwerk-Overheads cp remote_folder/* ~/local_folder/dauert eine reguläre Kopie jedoch sehr lange (10 Minuten).

Ich glaube, es liegt daran, dass die Dateien nacheinander kopiert werden - jede Datei wartet, bis die vorherige abgeschlossen ist, bevor der Kopiervorgang beginnt.

Was ist der einfachste Weg, um die Geschwindigkeit dieser Kopie zu erhöhen? (Ich gehe davon aus, dass die Kopie parallel ausgeführt werden soll.)

Das Komprimieren der Dateien vor dem Kopieren beschleunigt die Arbeit nicht unbedingt, da sie möglicherweise alle auf verschiedenen Datenträgern auf verschiedenen Servern gespeichert sind.

dsg
quelle
Das Komprimieren der Dateien vor dem Kopieren wird die Dinge massiv beschleunigen, da es keine weiteren "Hast du diese Datei bekommen?", "Ja, ich habe", "Hier ist die nächste", "Okay", ... Es sind diese "Turnarounds", die Sie verlangsamen.
David Schwartz
Es ist wahrscheinlich die Festplattengeschwindigkeit, und nicht die Netzwerkgeschwindigkeit, die Ihr begrenzender Faktor ist. Wenn dies der Fall ist, wird der Vorgang durch paralleles Ausführen pro Datei langsamer und nicht schneller, da Sie die Festplatte dazu zwingen, ständig hin und her zu suchen zwischen Dateien.
Joel Coehoorn
Während das Zippen möglicherweise keine gute Idee ist (das Ausführen der Komprimierung von mehr als 1000 Dateien kann eine Weile dauern), ist tar möglicherweise rentabel.
Rob
@JoelCoehoorn noch gibt es Fälle, in denen dies nicht der Fall ist: zB mehrere Spindeln + kleine Dateien (oder einfach zufällige Lesevorgänge). In diesem Szenario würde "parallel cp" helfen.
CAFxX

Antworten:

8

Solange Sie die ausgeführten Kopierbefehle einschränken, können Sie möglicherweise ein Skript wie das von Scrutinizer bereitgestellte verwenden

SOURCEDIR="$1"
TARGETDIR="$2"
MAX_PARALLEL=4
nroffiles=$(ls "$SOURCEDIR" | wc -w)
setsize=$(( nroffiles/MAX_PARALLEL + 1 ))
ls -1 "$SOURCEDIR"/* | xargs -n "$setsize" | while read workset; do
  cp -p "$workset" "$TARGETDIR" &
done
wait
OldWolf
quelle
1
Hinweis zur Warnung: Dieses Skript bricht mit Dateinamen ab, die Leerzeichen oder abschließende Zeichen enthalten.
Slhck
@OldWolf - Können Sie erklären, wie dieses Skript funktioniert? Welchen Teil übernimmt zum Beispiel die Parallelisierung?
dsg
3
@dsg: Am &Ende des cpBefehls kann die whileSchleife fortgesetzt und der nächste cp-Befehl gestartet werden, ohne zu warten. Der xargsBefehl übergibt die Dateinamen in 4er-Gruppen (MAX_PARALLEL) an die whileSchleife.
RedGrittyBrick
Hat bei mir nicht funktioniert. Ich bin nicht sicher, ob es möglich ist, zu beschleunigen cp. Offensichtlich können Sie die Berechnung durch das Multithreading beschleunigen . Aber ich denke nicht, dass dies auch für die Datenverarbeitung auf der Festplatte gilt.
Adobe
3

Eine Möglichkeit wäre, rsync zu verwenden, das nur die Änderungen kopiert - neue Dateien und die geänderten Teile anderer Dateien.

http://linux.die.net/man/1/rsync

Das Ausführen einer beliebigen Form des parallelen Kopiervorgangs wird wahrscheinlich Ihr Netzwerk überfluten und der Kopiervorgang wird nur zum Stillstand kommen oder an Engpässen auf der Quell- oder Zieldisk leiden.

Linker3000
quelle
2

Ehrlich gesagt ist das beste Tool Googles gsutil. Es werden parallele Kopien mit Verzeichnisrekursion verarbeitet. Die meisten anderen Methoden, die ich gesehen habe, können die Verzeichnisrekursion nicht verarbeiten. Sie erwähnen das lokale Dateisystem nicht ausdrücklich gegenüber lokalen Dateisystemkopien in ihren Dokumenten, aber es funktioniert wie ein Zauber.

Es ist eine weitere zu installierende Binärdatei, aber wahrscheinlich eine, die Sie bereits ausführen, wenn Sie die heutige Einführung von Cloud-Diensten in Betracht ziehen.

diq
quelle
2

Parallele Synchronisation mit find:

export SOURCE_DIR=/a/path/to/nowhere
export DEST_DIR=/another/path/to/nowhere

# sync folder structure first
rsync -a -f'+ */' -f'- *' $SOURCE_DIR $DEST_DIR

# cwd
cd $SOURCE_DIR

# use find to help filter files etc. into list and pipe into gnu parallel to run 4 rsync jobs simultaneously
find . -type f | SHELL=/bin/sh parallel --linebuffer --jobs=4 'rsync -av {} $DEST_DIR/{//}/'

In einem Unternehmens-LAN erreicht Single-Rsync etwa 800 Mbit / s. Mit 6-8 Jobs kann ich über 2,5 Gbit / s erreichen (auf Kosten der hohen Auslastung). Begrenzt durch die Scheiben.

yee379
quelle
0

Abhängig von der Topologie, die Sie haben, müssen Sie möglicherweise viele Dinge berücksichtigen. Bevor Sie jedoch über komplexe Lösungen nachdenken, können Sie einfach versuchen, die Aufgabe auf zwei Jobs aufzuteilen und zu prüfen, ob sich der Zeitaufwand erheblich verringert:

Das nächste Mal versuchen:

  cp remote_folder/[a-l]* ~/local_folder/ &
  cp remote_folder/[!a-l]* ~/local_folder/ &
  wait
  wait

(Möglicherweise möchten Sie [al] * durch etwas anderes ersetzen, das ungefähr der Hälfte der Dateien entspricht - möglicherweise [0-4] * - abhängig vom Inhalt des Ordners.)

Wenn sich die Zeit nicht dramatisch verbessert, ist es möglicherweise wichtiger zu prüfen, ob alle Dateien kopiert werden müssen (wie hoch ist das Verhältnis von geänderten Dateien zu allen Dateien?)

ktf
quelle