rsync zu mehreren Zielen mit derselben Dateiliste?

22

Ich frage mich, ob es mit rsync möglich ist, ein Verzeichnis auf mehrere entfernte Ziele gleichzeitig oder sogar parallel zu kopieren. (nicht notwendig, aber nützlich.)

Normalerweise würde etwas wie das Folgende gut funktionieren:

$ rsync -Pav /junk user@host1:/backup
$ rsync -Pav /junk user@host2:/backup
$ rsync -Pav /junk user@host3:/backup

Und wenn das die einzige Option ist, werde ich das nutzen. / Junk befindet sich jedoch auf einem langsamen Laufwerk mit ziemlich vielen Dateien, und die Neuerstellung der Dateiliste mit jeweils ~ 12.000 Dateien ist im Vergleich zur tatsächlichen Übertragung / Aktualisierung äußerst langsam (~ 5 Minuten). Ist es möglich, so etwas zu tun, um dasselbe zu erreichen:

$ rsync -Pav /junk user@host1:/backup user@host2:/backup user@host3:/backup 

Danke fürs schauen!

Jessie
quelle

Antworten:

12

Hier finden Sie Informationen aus der Manpage für rsync zum Batch-Modus.

BATCH-MODUS

Der Batch-Modus kann verwendet werden, um denselben Satz von Updates auf viele identische Systeme anzuwenden. Angenommen, man hat einen Baum, der auf mehreren Hosts repliziert wird. Nehmen wir nun an, dass einige Änderungen an diesem Quellbaum vorgenommen wurden und diese Änderungen auf die anderen Hosts übertragen werden müssen. Um dies im Batch-Modus zu tun, wird rsync mit der Option "Batch schreiben" ausgeführt, um die am Quellbaum vorgenommenen Änderungen auf einen der Zielbäume anzuwenden. Die Option "Batch schreiben" bewirkt, dass der rsync-Client alle Informationen, die zum Wiederholen dieses Vorgangs für andere identische Zielbäume erforderlich sind, in einer "Batch-Datei" speichert.

Durch das einmalige Generieren der Batch-Datei müssen Sie den Dateistatus, die Prüfsumme und die Datenblockgenerierung nicht mehrmals ausführen, wenn Sie mehrere Zielbäume aktualisieren. Multicast-Transportprotokolle können verwendet werden, um die Stapelaktualisierungsdateien parallel zu vielen Hosts gleichzeitig zu übertragen, anstatt die gleichen Daten an jeden Host einzeln zu senden.

Um die aufgezeichneten Änderungen auf einen anderen Zielbaum anzuwenden, führen Sie rsync mit der Option read-batch aus, und geben Sie den Namen derselben Batchdatei und den Zielbaum an. Rsync aktualisiert den Zielbaum anhand der in der Batch-Datei gespeicherten Informationen.

Zur Vereinfachung wird auch eine Skriptdatei erstellt, wenn die Option "Batch schreiben" verwendet wird: Sie trägt denselben Namen wie die Batchdatei, an die ".sh" angehängt ist. Diese Skriptdatei enthält eine Befehlszeile, die zum Aktualisieren eines Zielbaums mithilfe der zugehörigen Batchdatei geeignet ist. Es kann mithilfe einer Bourne-Shell (oder einer Bourne-ähnlichen Shell) ausgeführt werden, wobei optional ein alternativer Pfadname für den Zielbaum übergeben wird, der dann anstelle des ursprünglichen Zielpfads verwendet wird. Dies ist nützlich, wenn sich der Pfad der Zielstruktur auf dem aktuellen Host von dem unterscheidet, der zum Erstellen der Batchdatei verwendet wurde.

   Examples:

          $ rsync --write-batch=foo -a host:/source/dir/ /adest/dir/
          $ scp foo* remote:
          $ ssh remote ./foo.sh /bdest/dir/

          $ rsync --write-batch=foo -a /source/dir/ /adest/dir/
          $ ssh remote rsync --read-batch=- -a /bdest/dir/ <foo

In diesen Beispielen wird rsync zum Aktualisieren von / adest / dir / from / source / dir / verwendet, und die Informationen zum Wiederholen dieses Vorgangs werden in "foo" und "foo.sh" gespeichert. Der Host "remote" wird dann mit den gestapelten Daten aktualisiert, die in das Verzeichnis / bdest / dir abgelegt werden. Die Unterschiede zwischen den beiden Beispielen zeigen, wie flexibel Sie mit Chargen umgehen können:

  • Das erste Beispiel zeigt, dass die anfängliche Kopie nicht lokal sein muss. Sie können Daten je nach Bedarf mit der Remote-Shell-Syntax oder der rsync-Daemon-Syntax auf einen Remote-Host übertragen oder von einem Remote-Host abrufen.

  • Das erste Beispiel verwendet die erstellte Datei "foo.sh", um die richtigen rsync-Optionen zu erhalten, wenn der Befehl read-batch auf dem Remote-Host ausgeführt wird.

  • Im zweiten Beispiel werden die Stapeldaten über die Standardeingabe gelesen, sodass die Stapeldatei nicht zuerst auf die entfernte Maschine kopiert werden muss. In diesem Beispiel wird das Skript foo.sh vermieden, da eine geänderte Option --read-batch verwendet werden musste. Sie können die Skriptdatei jedoch bearbeiten, wenn Sie sie verwenden möchten (stellen Sie nur sicher, dass keine andere Option versucht, Standard zu verwenden Eingabe, z. B. die Option "--exclude-from = -".

    Vorsichtsmaßnahmen:

    Die Option "Stapel lesen" erwartet, dass die zu aktualisierende Zielstruktur mit der Zielstruktur identisch ist, die zum Erstellen der Dateigruppe für die Stapelaktualisierung verwendet wurde. Wenn ein Unterschied zwischen den Zielbäumen festgestellt wird, wird das Update möglicherweise mit einer Warnung verworfen (wenn die Datei bereits auf dem neuesten Stand zu sein scheint), oder es wird versucht, die Datei zu aktualisieren, und wenn die Datei nicht überprüft werden kann Wurde das Update mit einem Fehler verworfen. Dies bedeutet, dass es sicher sein sollte, einen Lesebatch-Vorgang erneut auszuführen, wenn der Befehl unterbrochen wurde. Wenn Sie die stapelweise Aktualisierung erzwingen möchten, unabhängig von der Größe und dem Datum der Datei, verwenden Sie die Option -I (beim Lesen des Stapels). Wenn ein Fehler auftritt, befindet sich der Zielbaum wahrscheinlich in einem teilweise aktualisierten Zustand. In diesem Fall,

    Die auf allen Zielen verwendete rsync-Version muss mindestens so neu sein wie die, die zum Generieren der Batch-Datei verwendet wurde. Rsync stirbt mit einem Fehler, wenn die Protokollversion in der Batch-Datei zu neu ist, als dass der Batch-Lesevorgang von Rsync verarbeitet werden könnte. Siehe auch die Option --protocol, um zu erfahren, wie das Erstellen von rsync eine Batch-Datei generiert, die ein älterer rsync verstehen kann. (Beachten Sie, dass das Format von Batch-Dateien in Version 2.6.3 geändert wurde, sodass das Mischen älterer Versionen mit neueren Versionen nicht funktioniert.)

    Wenn Sie eine Stapeldatei lesen, erzwingt rsync, dass der Wert bestimmter Optionen mit den Daten in der Stapeldatei übereinstimmt, wenn Sie nicht den gleichen Wert wie beim Befehl zum Schreiben im Stapel festgelegt haben. Andere Optionen können (und sollten) geändert werden. Beispielsweise wird "--write-batch" in "--read-batch" geändert, "--files-from" wird gelöscht, und die Optionen "--filter / - include / - exclude" werden nur benötigt, wenn eine der Optionen "--delete" angegeben ist .

    Der Code, der die Datei BATCH.sh erstellt, wandelt alle Filter- / Einschluss- / Ausschlussoptionen in eine einzelne Liste um, die als "hier" -Dokument an die Shell-Skriptdatei angehängt wird. Ein fortgeschrittener Benutzer kann dies verwenden, um die Ausschlussliste zu ändern, wenn eine Änderung dessen gewünscht wird, was von --delete gelöscht wird. Ein normaler Benutzer kann dieses Detail ignorieren und einfach das Shell-Skript verwenden, um den entsprechenden Befehl --read-batch für die gestapelten Daten auszuführen.

    Der ursprüngliche Batch-Modus in rsync basierte auf "rsync +", die neueste Version verwendet jedoch eine neue Implementierung.

Ich würde mir vorstellen, dass Sie es versuchen könnten

rsync --write-batch=foo -Pav /junk user@host1:/backup
foo.sh user@host2:/backup
foo.sh user@host3:/backup
Chloe
quelle
Der vorgeschlagene Befehl funktioniert nicht:remote destination is not allowed with --read-batch
kynan
Zeigen Sie den vollständigen Befehl an. -Ein Dateiname bedeutet, aus der Standardeingabe zu lesen, und STDIN wird fooim Beispiel auch aus einer lokalen Datei gelesen .
Chloe
2
Dies scheint die maximal richtige Lösung für das zu sein, was ich versucht habe, obwohl mein Anwendungsfall dafür längst in den Äther verdunstet ist. : D
Jessie
4

Sie könnten versuchen, unisono zu verwenden . Das Erstellen der Dateiliste sollte wesentlich schneller gehen, da ein Cache der Dateien gespeichert wird.

Jason Axelson
quelle
2
Hinweis: Unison speichert die Dateien nicht im Cache. Es werden nur die Dateinamen, Zeitstempel und Prüfsummen in einer Datenbank gespeichert. Es wird immer noch ein Scan des Dateisystems durchgeführt und eine Prüfsumme zum Vergleich mit der Fernbedienung erstellt. Der einzige Vorteil von Unison ist die bidirektionale Synchronisierung. Ich empfehle Unison, aber es wird hier nicht helfen.
Chloe
4

Das rsync --batch-modeunterstützt Multicast. Wenn dies in Ihrem Netzwerk möglich ist, lohnt es sich möglicherweise, dies zu prüfen.

Codecrank
quelle
2

Wie wäre es mit einem Dateisystemwechsel?

Vor einiger Zeit habe ich einen Multi-Terabyte-FS von ext3 auf XFS umgestellt. Die Zeit zum Durchsuchen der Verzeichnisse (mit ungefähr 600.000 Dateien, die ich das letzte Mal überprüft habe) ging von 15 bis 17 Minuten auf weniger als 30 Sekunden!

Javier
quelle
1

Keine direkte Antwort, aber wenn Sie rsync Version 3+ verwenden, beginnt die Übertragung, bevor die gesamte Dateiliste generiert wird.

Eine andere Option, die immer noch nicht sehr effizient ist, besteht darin, sie als Jobs auszuführen, sodass einige gleichzeitig ausgeführt werden.

Außerdem habe ich gerade an diese Seltsamkeit gedacht, wenn es Ihnen nichts ausmacht, Teer zu verwenden:

tar cf - . | tee >(ssh localhost 'cat > test1.tar') >(ssh localhost 'cat > test2.tar') >/dev/null

Wobei jeder localhost natürlich andere Server sein würde (setzt eine schlüsselbasierte Anmeldung voraus). Ich habe das oben genannte allerdings noch nie benutzt.

Kyle Brandt
quelle
Hmm! Seltsamerweise scheint cwrsync (rsync 3.0.7) das nicht zu tun. Ich muss mir aber ansehen, warum das so ist, da dies eine große Hilfe wäre, um diese enormen Laufzeiten zu verkürzen. Vielen Dank!
Jessie
Diese Version auf beiden Seiten?
Kyle Brandt
Nicht wirklich; der lokale Rechner ist cwrsync 3.0.7 und der entfernte Host (der, mit dem ich gerade arbeite) ist rsync 3.0.3 unter Debian Lenny. Das scheint kein zu großer Versionsunterschied zu sein, um sich schlecht zu benehmen, aber ich weiß nicht .. Ich werde versuchen, die Debian-Seite zu aktualisieren.
Jessie
1
Was für ein seltsamer kleiner Einzeiler. Das würde wahrscheinlich funktionieren, wenn ich nicht die Tatsache ausnutzen würde, dass rsync nicht einige Datenmengen über mehrere langsame Verbindungen reduzieren muss, wenn sich höchstens ein paar Hundert KB geändert haben. Auch wenn beide Seiten von (cw) rsync 3.0.7 erreicht wurden, wurde immer noch eine Dateiliste erstellt und seriell übertragen. Aber nicht zu sehr darüber besorgt.
Jessie
Ist nicht "tar cf -" das gleiche wie "tar c." ?
Johan Boulé
1

Wie wäre es, wenn Sie die rsync-Jobs von Host1, Host2 und Host3 ausführen würden? Oder führen Sie einen Job zum Kopieren auf Host1 aus und führen Sie ihn dann auf Host2 und Host3 aus, um ihn von Host1 abzurufen.

mfinni
quelle
1

Eine bessere Lösung wäre, ein Repository mit git zu erstellen und nur auf die 3 Hosts zu pushen. Schneller würden Sie den Dateilistenteil nicht benötigen und es verbraucht weniger Ressourcen.

Viel Glück,
João Miguel Neves

jneves
quelle
10
git behält weder Änderungszeiten noch Berechtigungen bei (mit Ausnahme des Ausführungsbits) und würde das Speichern einer zweiten Kopie der Daten als git-Objekte erfordern, .git/obwohl Push-Vorgänge zu den Fernbedienungen, die bereits die meisten Daten hätten, schneller wären. git ist kein Ersatz für rsync.
Dan D.
Außerdem ist Git öffentlich einsehbar, sofern Sie nicht bezahlen.
Chloe
8
@Chloe, du verwechselst GitHub. Git selbst ist kostenlos Open - Source verteiltes Versionskontrollsystem, und jeder kann Host Git Repository mit allen Mitteln, einschließlich http, nfsund afp. GitHub ist eine Website, die sich um die Erstellung und Pflege von Git-Repos kümmert und diese öffentlich macht (sofern Sie nicht bezahlen).
Turiningen
1
@Chloe GitHub ist öffentlich sichtbar, aber BitBucket bietet private Repos.
SWS
2
Außerdem verfolgt Git leere Verzeichnisse nicht.
Flimm
1

Wenn Sie selbst nach dieser Antwort suchen, müssen Sie wahrscheinlich zuerst mit rsync einen Stapel erstellen und ihn dann an alle senden. Dann müsste die Dateiliste nur einmal erstellt werden, und dann könnten Sie es einfach tun Hintergrund alle drei rsyncs, um sie parallel auszuführen.

Morgan
quelle
1

Eine andere mögliche Lösung besteht darin, so viele rsync-Prozesse parallel auszuführen, wie Hosts vorhanden sind, z. B. fork.

Alexey Tigarev
quelle