Parallelisieren Sie Rsync mit GNU Parallel

18

Ich habe ein rsyncSkript verwendet, um Daten auf einem Host mit den Daten auf einem anderen Host zu synchronisieren. Die Daten enthalten zahlreiche kleine Dateien, die zu fast 1,2 TB beitragen.

Um diese Dateien zu synchronisieren, habe ich den rsyncBefehl wie folgt verwendet:

rsync -avzm --stats --human-readable --include-from proj.lst /data/projects REMOTEHOST:/data/

Die Inhalte von proj.lst lauten wie folgt:

+ proj1
+ proj1/*
+ proj1/*/*
+ proj1/*/*/*.tar
+ proj1/*/*/*.pdf
+ proj2
+ proj2/*
+ proj2/*/*
+ proj2/*/*/*.tar
+ proj2/*/*/*.pdf
...
...
...
- *

Als Test habe ich zwei dieser Projekte (8,5 GB Daten) ausgewählt und den obigen Befehl ausgeführt. Da es sich um einen sequentiellen Prozess handelt, dauert der Vorgang 14 Minuten und 58 Sekunden. Für 1,2 TB Daten würde es also mehrere Stunden dauern.

Wenn ich mehrere würde könnte rsyncProzesse parallel (unter Verwendung von &, xargsoder parallel), wäre es meine Zeit sparen.

Ich habe versucht mit dem folgenden Befehl parallel(nachdem ich cdin das Quellverzeichnis gegangen bin ) und es dauerte 12 Minuten 37 Sekunden, um auszuführen:

parallel --will-cite -j 5 rsync -avzm --stats --human-readable {} REMOTEHOST:/data/ ::: .

Dies hätte 5-mal weniger Zeit in Anspruch nehmen sollen, tat es aber nicht. Ich denke, ich gehe irgendwo falsch.

Wie kann ich mehrere rsyncProzesse ausführen, um die Ausführungszeit zu verkürzen?

Mandar Shinde
quelle
1
Sind Sie durch die Netzwerkbandbreite begrenzt? Disk iops? Festplattenbandbreite?
Ole Tange
Wenn möglich, möchten wir 50% der gesamten Bandbreite nutzen. Die Parallelisierung mehrerer rsyncs ist jedoch unsere oberste Priorität.
Mandar Shinde
Können Sie uns Folgendes mitteilen: Netzwerkbandbreite, Festplatten-Iops, Festplattenbandbreite und tatsächlich verwendete Bandbreite?
Ole Tange
Tatsächlich kenne ich die obigen Parameter nicht. Den Optimierungsteil können wir vorerst vernachlässigen. Multiple rsyncs parallel stehen jetzt im Vordergrund.
Mandar Shinde
Es macht keinen Sinn, parallel zu arbeiten, wenn die Einschränkung nicht die CPU ist. Dies kann / wird die Situation sogar verschlimmern (widersprüchliche Bewegungen des Plattenarms auf der Quell- oder Zielplatte).
Xenoid

Antworten:

16

Folgende Schritte haben den Job für mich erledigt:

  1. Führen Sie den rsync --dry-runersten aus, um die Liste der betroffenen Dateien abzurufen.
$ rsync -avzm --stats --safe-links --ignore-existing --dry-run \
    --human-readable /data/projects REMOTE-HOST:/data/ > /tmp/transfer.log
  1. Ich habe die Ausgabe von cat transfer.logto eingespeist parallel, um 5 rsyncs parallel laufen zu lassen :
$ cat /tmp/transfer.log | \
    parallel --will-cite -j 5 rsync -avzm --relative \
      --stats --safe-links --ignore-existing \
      --human-readable {} REMOTE-HOST:/data/ > result.log

Hier hat --relativeOption ( Link ) dafür gesorgt, dass die Verzeichnisstruktur für die betroffenen Dateien an der Quelle und am Ziel unverändert bleibt (innerhalb des /data/Verzeichnisses), sodass der Befehl im Quellordner ausgeführt werden muss (z /data/projects. B. ).

Mandar Shinde
quelle
5
Das würde eine rsync pro Datei machen. Es wäre wahrscheinlich effizienter, die gesamte Dateiliste unter Verwendung splitdieser Dateinamen aufzuteilen und parallel zu übertragen. Verwenden Sie dann rsync --files-from, um die Dateinamen aus jeder Datei zu entfernen und sie zu synchronisieren. rm backups. * split -l 3000 backup.list backups. ls Backups. * | Paralleler Zeilenpuffer --verbose -j 5 rsync --progress -av --files-from {} / LOCAL / PARENT / PATH / REMOTE_HOST: REMOTE_PATH /
Sandip Bhattacharya
1
Wie behandelt der zweite Befehl rsync die Zeilen in result.log, die keine Dateien sind? dh receiving file list ... done created directory /data/.
Mike D
1
In neueren Versionen von rsync (3.1.0+) können Sie --info=nameanstelle von verwenden -v, und Sie erhalten nur die Namen der Dateien und Verzeichnisse. Möglicherweise möchten Sie --protect-args auch für das 'innere' übertragende rsync verwenden, wenn Dateien Leerzeichen oder Shell-Metazeichen enthalten.
Cheetah
13

Ich persönlich benutze dieses einfache:

ls -1 | parallel rsync -a {} /destination/directory/

Dies ist nur dann nützlich, wenn Sie mehr als ein paar nicht nahezu leere Verzeichnisse haben, da sonst fast alle rsyncbeendet werden und das letzte den ganzen Job alleine erledigt.

Julien Palard
quelle
Das funktioniert großartig - schwer zu wissen, ob es irgendetwas tut, also macht ein -v zu parallel es gesprächiger. Außerdem werden mit -j 30 to parallel (dh vor dem Befehl rsync) 30 Jobs ausgeführt, nicht nur einer pro CPU-Kern, was der Standard ist.
Criggie
12

Ich würde niemanden davon abhalten, die akzeptierte Antwort zu verwenden. Eine bessere Lösung besteht darin, das Verzeichnis der obersten Ebene zu crawlen und eine proportionale Anzahl von Rync-Vorgängen zu starten.

Ich habe ein großes ZFS-Volume und meine Quelle war ein CIFS-Mount. Beide sind mit 10G verbunden und können in einigen Benchmarks die Verbindung sättigen. Die Leistung wurde mit bewertetzpool iostat 1 .

Das Quelllaufwerk wurde wie folgt gemountet:

mount -t cifs -o username=,password= //static_ip/70tb /mnt/Datahoarder_Mount/ -o vers=3.0

Mit einem einzigen rsyncProzess:

rsync -h -v -r -P -t /mnt/Datahoarder_Mount/ /StoragePod

das io meter lautet:

StoragePod  30.0T   144T      0  1.61K      0   130M
StoragePod  30.0T   144T      0  1.61K      0   130M
StoragePod  30.0T   144T      0  1.62K      0   130M

In synthetischen Benchmarks (Crystal Disk) erreicht die Leistung für sequentielles Schreiben 900 MB / s, was bedeutet, dass die Verbindung gesättigt ist. 130MB / s ist nicht sehr gut, und der Unterschied zwischen einem Wochenende und zwei Wochen warten.

Also habe ich die Dateiliste erstellt und versucht, die Synchronisierung erneut auszuführen (ich habe einen 64-Core-Computer):

cat /home/misha/Desktop/rsync_logs_syncs/Datahoarder_Mount.log | parallel --will-cite -j 16 rsync -avzm --relative --stats --safe-links --size-only --human-readable {} /StoragePod/ > /home/misha/Desktop/rsync_logs_syncs/Datahoarder_Mount_result.log

und es hatte die gleiche Leistung!

StoragePod  29.9T   144T      0  1.63K      0   130M
StoragePod  29.9T   144T      0  1.62K      0   130M
StoragePod  29.9T   144T      0  1.56K      0   129M

Als Alternative habe ich einfach rsync für die Root-Ordner ausgeführt:

rsync -h -v -r -P -t /mnt/Datahoarder_Mount/Mikhail/Marcello_zinc_bone /StoragePod/Marcello_zinc_bone
rsync -h -v -r -P -t /mnt/Datahoarder_Mount/Mikhail/fibroblast_growth /StoragePod/fibroblast_growth
rsync -h -v -r -P -t /mnt/Datahoarder_Mount/Mikhail/QDIC /StoragePod/QDIC
rsync -h -v -r -P -t /mnt/Datahoarder_Mount/Mikhail/sexy_dps_cell /StoragePod/sexy_dps_cell

Dies hat die Leistung tatsächlich gesteigert:

StoragePod  30.1T   144T     13  3.66K   112K   343M
StoragePod  30.1T   144T     24  5.11K   184K   469M
StoragePod  30.1T   144T     25  4.30K   196K   373M

Als Fazit, als @Sandip Bhattacharya auftauchte, schreiben Sie ein kleines Skript, um die Verzeichnisse zu erhalten und parallel dazu. Alternativ können Sie eine Dateiliste an rsync übergeben. Erstellen Sie jedoch nicht für jede Datei neue Instanzen.

Mikhail
quelle
5

Eine getestete Methode zur parallelisierten Synchronisierung ist: http://www.gnu.org/software/parallel/man.html#EXAMPLE:-Parallelizing-rsync

rsync ist ein großartiges Tool, das jedoch manchmal die verfügbare Bandbreite nicht ausfüllt. Dies ist häufig ein Problem beim Kopieren mehrerer großer Dateien über Hochgeschwindigkeitsverbindungen.

Das Folgende startet eine rsync pro große Datei in src-dir, um auf dem Server fooserver zu dest-dir:

cd src-dir; find . -type f -size +100000 | \
parallel -v ssh fooserver mkdir -p /dest-dir/{//}\; \
  rsync -s -Havessh {} fooserver:/dest-dir/{} 

Die erstellten Verzeichnisse haben möglicherweise falsche Berechtigungen und kleinere Dateien werden nicht übertragen. So beheben Sie, dass rsync ein letztes Mal ausgeführt wird:

rsync -Havessh src-dir/ fooserver:/dest-dir/ 

Wenn Sie keine Daten übertragen können, diese aber abrufen müssen und die Dateien digits.png heißen (z. B. 000000.png), können Sie möglicherweise Folgendes tun:

seq -w 0 99 | parallel rsync -Havessh fooserver:src/*{}.png destdir/
Ole Tange
quelle
Irgendeine andere Alternative, um das zu vermeiden find?
Mandar Shinde
1
Begrenzen Sie die maximale Fundtiefe.
Ole Tange
Wenn ich die --dry-runOption in verwende rsync, hätte ich eine Liste der Dateien, die übertragen werden würden. Kann ich diese Dateiliste zur Verfügung stellen, parallelum den Prozess zu parallelisieren?
Mandar Shinde
1
cat dateien | parallel -v ssh fooserver mkdir -p / dest-dir / {//} \; rsync -s -Havessh {} fooserver: / dest-dir / {}
Ole Tange
Kannst du mir bitte den mkdir -p /dest-dir/{//}\;Teil erklären ? Besonders die {//}Sache ist etwas verwirrend.
Mandar Shinde
1

Für Synchronisierungen mit mehreren Zielen verwende ich

parallel rsync -avi /path/to/source ::: host1: host2: host3:

Hinweis: Alle SSH-Verbindungen werden mit öffentlichen Schlüsseln in hergestellt ~/.ssh/authorized_keys

Ingopingo
quelle
1

Ich google immer nach parallelem rsync, da ich immer den vollständigen Befehl vergesse, aber bei mir hat keine Lösung funktioniert, wie ich wollte - entweder umfasst sie mehrere Schritte oder muss installiert werden parallel. Am Ende habe ich diesen Einzeiler zum Synchronisieren mehrerer Ordner verwendet:

find dir/ -type d|xargs -P 5 -I % sh -c 'rsync -a --delete --bwlimit=50000 $(echo dir/%/ host:/dir/%/)'

-P 5 ist die Anzahl der Prozesse, die Sie erzeugen möchten - verwenden Sie 0 für unbegrenzt (offensichtlich nicht empfohlen).

--bwlimit zu vermeiden, die gesamte Bandbreite zu nutzen.

-I %Argument von find (Verzeichnis gefunden in dir/)

$(echo dir/%/ host:/dir/%/)- druckt Quell- und Zielverzeichnisse, die von rsync als Argumente gelesen werden. % wird durch den von gefundenen xargsVerzeichnisnamen ersetztfind .

Nehmen wir an, ich habe zwei Verzeichnisse in /home: dir1und dir2. Ich renne find /home -type d|xargs -P 5 -I % sh -c 'rsync -a --delete --bwlimit=50000 $(echo /home/%/ host:/home/%/)'. Der Befehl rsync wird also als zwei Prozesse ausgeführt (zwei Prozesse, weil er /homezwei Verzeichnisse hat) und hat folgende Argumente:

rsync -a --delete --bwlimit=50000 /home/dir1/ host:/home/dir1/
rsync -a --delete --bwlimit=50000 /home/dir1/ host:/home/dir1/
Sebastjanas
quelle