So spiegeln Sie einen gesamten ZFS-Pool einseitig in einen anderen ZFS-Pool

So spiegeln Sie einen gesamten ZFS-Pool einseitig in einen anderen ZFS-Pool

Ich habe einen ZFS-Pool mit mehreren Zvols und Datasets, von denen einige auch verschachtelt sind. Von allen Datasets und Zvols werden regelmäßig Snapshots von zfs-auto-snapshot erstellt. Von allen Datasets und Zvols gibt es auch einige manuell erstellte Snapshots.

Ich habe einen Remote-Pool eingerichtet, bei dem aus Zeitmangel das erste Kopieren über das lokale Hochgeschwindigkeitsnetzwerk per zfs send -R nicht abgeschlossen werden konnte (einige Datasets fehlen, einige Datasets haben veraltete oder fehlende Snapshots).

Jetzt ist der Pool physisch über eine langsame Verbindung remote und ich muss den Remote-Pool regelmäßig mit dem lokalen Pool synchronisieren, d. h. im lokalen Pool vorhandene Daten müssen in den Remote-Pool kopiert werden, aus dem lokalen Pool verschwundene Daten müssen aus dem Remote-Pool gelöscht werden und im Remote-Pool vorhandene, aber nicht im lokalen Pool vorhandene Daten müssen aus dem Remote-Pool gelöscht werden, wobei mit „Daten“ „Zvols“, „Datasets“ oder „Snapshots“ gemeint sind.

Wenn ich dies zwischen zwei regulären Dateisystemen mit rsync machen würde, wäre es „-axPHAX --delete“ (das mache ich tatsächlich, um einige Systeme zu sichern).

Wie richte ich eine Synchronisierungsaufgabe ein, damit die Zvols und Datensätze des Remote-Pools (einschließlich ihrer Snapshots) mit lokalen Zvols, Datensätzen und Snapshots synchronisiert werden können?

Ich möchte die Übertragung über SSH vermeiden, da SSH einen niedrigen Durchsatz bietet. Stattdessen würde ich Mbuffer oder iscsi bevorzugen.

Antwort1

Haftungsausschluss: Da ich Zvols noch nie verwendet habe, kann ich nicht sagen, ob sie sich bei der Replikation von normalen Dateisystemen oder Snapshots unterscheiden. Ich gehe davon aus, dass dies der Fall ist, aber verlassen Sie sich nicht auf mein Wort.


Ihre Frage besteht eigentlich aus mehreren Fragen. Ich versuche, sie einzeln zu beantworten:

So replizieren/spiegeln Sie den gesamten Pool an einem Remote-Standort

Sie müssen die Aufgabe in zwei Teile aufteilen: Zuerst muss die erste Replikation abgeschlossen sein, danach ist eine inkrementelle Replikation möglich,solange Sie Ihre Replikations-Snapshots nicht verändern. Um die inkrementelle Replikation zu aktivieren, müssen Sie die letzten Replikations-Snapshots beibehalten. Alles davor kann gelöscht werden. Wenn Sie den vorherigen Snapshot löschen, zfs recvwird eine Fehlermeldung angezeigt und die Replikation wird abgebrochen. In diesem Fall müssen Sie wieder von vorne beginnen. Versuchen Sie daher, dies zu vermeiden.

Wenn Sie nur die richtigen Optionen benötigen, sind diese:

  • zfs send:
    • -R: alles unter dem angegebenen Pool oder Datensatz senden (rekursive Replikation, immer erforderlich, umfasst -p). Beim Empfang werden außerdem alle gelöschten Quell-Snapshots am Ziel gelöscht.
    • -I: alle Zwischen-Snapshots zwischen dem letzten Replikations-Snapshot und dem aktuellen Replikations-Snapshot einschließen (nur bei inkrementellen Sendungen erforderlich)
  • zfs recv:
    • -F: Zielpool erweitern, einschließlich der Löschung vorhandener Datensätze, die auf der Quelle gelöscht werden
    • -d: verwerfen Sie den Namen des Quellpools und ersetzen Sie ihn durch den Namen des Zielpools (die restlichen Dateisystempfade bleiben erhalten und werden bei Bedarf ebenfalls erstellt)
    • -u: Dateisystem nicht am Ziel mounten

Wenn Sie ein vollständiges Beispiel bevorzugen, finden Sie hier ein kleines Skript:

#!/bin/sh

# Setup/variables:

# Each snapshot name must be unique, timestamp is a good choice.
# You can also use Solaris date, but I don't know the correct syntax.
snapshot_string=DO_NOT_DELETE_remote_replication_
timestamp=$(/usr/gnu/bin/date '+%Y%m%d%H%M%S')
source_pool=tank
destination_pool=tank
new_snap="$source_pool"@"$snapshot_string""$timestamp"
destination_host=remotehostname

# Initial send:

# Create first recursive snapshot of the whole pool.
zfs snapshot -r "$new_snap"
# Initial replication via SSH.
zfs send -R "$new_snap" | ssh "$destination_host" zfs recv -Fdu "$destination_pool"

# Incremental sends:

# Get old snapshot name.
old_snap=$(zfs list -H -o name -t snapshot -r "$source_pool" | grep "$source_pool"@"$snapshot_string" | tail --lines=1)
# Create new recursive snapshot of the whole pool.
zfs snapshot -r "$new_snap"
# Incremental replication via SSH.
zfs send -R -I "$old_snap" "$new_snap" | ssh "$destination_host" zfs recv -Fdu "$destination_pool"
# Delete older snaps on the local source (grep -v inverts the selection)
delete_from=$(zfs list -H -o name -t snapshot -r "$source_pool" | grep "$snapshot_string" | grep -v "$timestamp")
for snap in $delete_from; do
    zfs destroy "$snap"
done

Verwenden Sie etwas Schnelleres als SSH

Wenn Sie über eine ausreichend gesicherte Verbindung verfügen, beispielsweise IPSec- oder OpenVPN-Tunnel und ein separates VLAN, das nur zwischen Sender und Empfänger besteht, können Sie von SSH auf unverschlüsselte Alternativen wie mbuffer umsteigen.wie hier beschrieben, oder Sie könnten SSH mit schwacher/keiner Verschlüsselung und deaktivierter Komprimierung verwenden,Das ist hier ausführlich beschrieben. Es gab auch eine Website zum Thema Neukomprimierung von SSH, um es viel schneller zu machen, aber leider erinnere ich mich nicht an die URL – ich werde sie später bearbeiten, wenn ich sie finde.

Bei sehr großen Datensätzen und langsamen Verbindungen kann es auch sinnvoll sein, die erste Übertragung über die Festplatte durchzuführen (verwenden Sie eine verschlüsselte Festplatte, um zpool zu speichern, und übermitteln Sie es in einem versiegelten Paket per Kurier, Post oder persönlich). Da die Übertragungsmethode für Senden/Empfangen keine Rolle spielt, können Sie alles auf die Festplatte leiten, den Pool exportieren, die Festplatte an ihr Ziel senden, den Pool importieren und dann alle inkrementellen Sendungen über SSH übertragen.

Das Problem mit verpfuschten Schnappschüssen

Wie bereits erwähnt, erhalten Sie beim Löschen/Ändern Ihrer Replikations-Snapshots die Fehlermeldung

cannot send 'pool/fs@name': not an earlier snapshot from the same fs

Das bedeutet, dass entweder Ihr Befehl falsch war oder Sie sich in einem inkonsistenten Zustand befinden, in dem Sie die Snapshots entfernen und von vorne beginnen müssen.

Dies hat mehrere negative Auswirkungen:

  1. Sie können einen Replikations-Snapshot erst löschen, wenn der neue Replikations-Snapshot erfolgreich übertragen wurde. Da diese Replikations-Snapshots den Status aller anderen (älteren) Snapshots enthalten, wird leerer Speicherplatz gelöschter Dateien und Snapshots erst freigegeben, wenn die Replikation abgeschlossen ist. Dies kann zu temporären oder permanenten Speicherplatzproblemen in Ihrem Pool führen, die Sie nur beheben können, indem Sie den gesamten Replikationsvorgang neu starten oder abschließen.
  2. Sie werden über viele zusätzliche Snapshots verfügen, was den Listenbefehl verlangsamt (außer unter Oracle Solaris 11, wo dies behoben wurde).
  3. Möglicherweise müssen Sie die Snapshots vor (versehentlichem) Löschen schützen, außer durch das Skript selbst.

Es gibt eine mögliche Lösung für diese Probleme, aber ich habe sie selbst noch nicht ausprobiert. Sie könnten verwenden zfs bookmark, eine neue Funktion in OpenSolaris/illumos, die speziell für diese Aufgabe entwickelt wurde. Dies würde Sie von der Snapshot-Verwaltung befreien. Der einzige Nachteil ist, dass es derzeit nur für einzelne Datensätze funktioniert und nicht rekursiv. Sie müssten eine Liste aller Ihrer alten und neuen Datensätze speichern und dann eine Schleife über sie ausführen, sie mit Lesezeichen versehen, senden und empfangen und dann die Liste (oder kleine Datenbank, wenn Sie das bevorzugen) aktualisieren.

Wenn Sie es mit dem Lesezeichen versuchen, würde mich interessieren, wie es für Sie geklappt hat!

Antwort2

Persönlich würde ich mir eine Liste von Zvols, Datasets usw. auf dem Remote-Server erstellen, dienichtHalten Sie aktuelle Snapshots bereit und aktualisieren Sie diese Snapshots anschließend mit zfs send, auch wenn dies zeitaufwändig ist und viel Bandbreite verbraucht.

Dann könnte ich einfach von da an weitermachen zfs sendund muss nicht das Rad neu erfinden, indem ich meinen eigenen Synchronisationscode schreibe. rsyncist gut für ältere Dateisysteme, aber zfs sendviel besser für ZFS - es weißgenauwelche Blöcke sich im Snapshot geändert haben und sendetnursie, während rsync einzelne Dateien und/oder Zeitstempel zwischen lokalen und Remote-Servern vergleichen muss. Gleiches gilt btrfs sendfür BTRFS-Pools.

Wenn Sie nur eine kleine Anzahl von Snapshots haben, die aktualisiert werden müssen, kann dies manuell erfolgen. Andernfalls benötigen Sie für die automatische Aktualisierung eine Liste der neuesten lokalen Snapshots im Vergleich zu Remote-Snapshots sowie ein Skript zum Vergleichen der Versionen und dann der zfs sendlokalen Snapshots, die auf dem rmeote-Server veraltet sind.

Das reicht aus, wenn Sie nur den neuesten Snapshot für jeden Datensatz benötigen. Wenn Sie alle vorherigen Snapshots benötigen, muss Ihr Skript diese natürlich auch verarbeiten ... und das wird VIEL komplizierter. In einigen Fällen müssen Sie möglicherweise auf dem Remote-Server ein Rollback durchführen, damit Sie die Zwischen-/fehlenden Snapshots erneut senden können.

Wenn Sie eine sichere Verbindung zum Remote-Server wünschen, haben Sie eigentlich keine andere Wahl, als zu verwenden ssh– oder vielleicht mit oder so etwas einen Tunnel einzurichten openvpnund zu verwenden netcat.

Antwort3

Schauen Sie sich `zrepl' auf FreeBSD an, es könnte Ihr Leben, und das aller anderen, um einiges einfacher machen. Es wurde vor ein paar Tagen während der BSDCan2018 in Ottawa vorgestellt. Es sieht vielversprechend aus und könnte eine Lösung für Ihre Probleme sein.

Antwort4

zrep ist eine nette All-in-One-Lösung UND verfügt über Dokumentation und Hooks, wie man schnellere Übertragungen als mit einfachen SSH-Übertragungen erreicht

https://github.com/bolthole/zrep

es ist auch plattformübergreifend: unterstützt auf Linux, FreeBSD und Solaris/Illumos

verwandte Informationen