Synchronisieren Sie LVM-Snapshots mit dem Sicherungsserver

22

Ich habe eine Reihe von virtuellen Xen-Maschinen, die auf einer Reihe von Linux-Servern ausgeführt werden. Diese VMs speichern ihre Festplatten-Images in Linux-LVM-Volumes mit Gerätenamen wie / dev / xenVG / SERVER001OS usw. Ich möchte regelmäßig Backups dieser Festplattenimages erstellen, damit ich die VMs bei Bedarf wiederherstellen kann (die LVM-Geräte werden bereits mit DRBD zwischen jeweils zwei physischen Computern gespiegelt, ich bin hier nur besonders paranoid).

Wie gehe ich vor? Der erste Schritt besteht offensichtlich darin, ein Snapshot des LVM-Geräts zu erstellen. Wie übertrage ich dann die Daten so effizient wie möglich auf einen Sicherungsserver? Ich könnte einfach das ganze Gerät kopieren, etwa so:

dd if=/dev/xenVG/SERVER001OS | ssh administrator@backupserver "dd of=/mnt/largeDisk/SERVER001OS.img"

... aber das würde viel Bandbreite kosten. Gibt es ein Rsync-ähnliches Tool zum Synchronisieren des Inhalts ganzer Festplattenblöcke zwischen Remoteservern? So etwas wie:

rsync /dev/xenVG/SERVER001OS backupServer:/mnt/largeDisk/SERVER001OS.img

Wenn ich die Manpage von rsync richtig verstehe, funktioniert der obige Befehl nicht wirklich (oder?), Aber er zeigt, was ich anstrebe. Ich verstehe, dass die Option --devices rsync darin besteht, Geräte selbst zu kopieren, nicht den Inhalt dieser Geräte. Das Erstellen einer lokalen Kopie des VM-Images vor dem Synchronisieren mit dem Remote-Server ist keine Option, da nicht genügend Speicherplatz vorhanden ist.

Gibt es ein praktisches Dienstprogramm, das zwischen Blockgeräten und einer Sicherungsdatei auf einem Remote-Server synchronisiert werden kann? Ich kann eine schreiben, wenn ich muss, aber eine bestehende Lösung wäre besser. Habe ich eine rsync-Option verpasst, die dies für mich erledigt?

David Hicks
quelle

Antworten:

12

Standard-Rsync fehlt diese Funktion, aber es gibt einen Patch dafür im Rsync-Patch-Tarball (copy-devices.diff), der von http://rsync.samba.org/ftp/rsync/ heruntergeladen werden kann. Nach dem Anwenden und erneuten Kompilieren können Sie Geräte mit der Option --copy-devices synchronisieren.

Balázs Pozsár
quelle
Wenn es sich bei Ihrem Ziel um ein Gerät handelt, befindet sich der Patch hier: bugzilla.redhat.com/show_bug.cgi?id=1193654
Jason Pyeron
16

Obwohl es Patches für Schreibgeräte und Kopiergeräte für RSync gibt, funktionieren sie nur bei kleinen Images (1 bis 2 GB). RSync wird eine Ewigkeit damit verbringen, nach passenden Blöcken für größere Bilder zu suchen, und es sind fast 40 GB oder größere Geräte / Dateien unbrauchbar.

Wir verwenden Folgendes, um einen Prüfsummenvergleich pro 1 MB durchzuführen und kopieren dann einfach den Inhalt, wenn er nicht übereinstimmt. Wir verwenden dies, um Server auf einem virtuellen Host in den USA über das öffentliche Internet auf einem Sicherungssystem in Großbritannien zu sichern. Sehr wenig CPU-Aktivität und Snapshot-Leistungseinbußen treten erst nach Stunden auf:

Schnappschuss erstellen:

lvcreate -i 2 -L 25G /dev/vg_kvm/company-exchange -n company-exchange-snap1

export dev1='/dev/mapper/vg_kvm-company--exchange--snap1';
export dev2='/dev/mapper/vg_kvm-company--exchange';
export remote='[email protected]';

Initial Seeding:

dd if=$dev1 bs=100M | gzip -c -9 | ssh -i /root/.ssh/rsync_rsa $remote "gzip -dc | dd of=$dev2"

Inkrementelle nächtliche Sicherung (sendet nur geänderte Blöcke):

ssh -i /root/.ssh/rsync_rsa $remote "
  perl -'MDigest::MD5 md5' -ne 'BEGIN{\$/=\1024};print md5(\$_)' $dev2 | lzop -c" |
  lzop -dc | perl -'MDigest::MD5 md5' -ne 'BEGIN{$/=\1024};$b=md5($_);
    read STDIN,$a,16;if ($a eq $b) {print "s"} else {print "c" . $_}' $dev1 | lzop -c |
ssh -i /root/.ssh/rsync_rsa $remote "lzop -dc |
  perl -ne 'BEGIN{\$/=\1} if (\$_ eq\"s\") {\$s++} else {if (\$s) {
    seek STDOUT,\$s*1024,1; \$s=0}; read ARGV,\$buf,1024; print \$buf}' 1<> $dev2"

Schnappschuss entfernen:

lvremove -f company-exchange-snap1
sysadmin1138
quelle
Zuerst hatte ich Angst, aber dann habe ich es ausprobiert und es funktioniert wirklich.
Martin
Warum read ARGV,$buf,1024anstelle von read STDIN,$buf,1024@ sysadmin1138? (Ich versuche auf stackoverflow.com/q/22693823/2987828 zu antworten und verstehe ARGV hier nicht). Ich benutze jeden Tag die Variante in der Frage stackoverflow.com/q/22693823/2987828 und es funktioniert gut.
User2987828
1
Siehe perlmonks.org/bare/?node_id=492858, in dem angegeben ist, dass ARGV und STDIN ähnlich sind, sofern kein Dateiname als Argument angegeben wird.
User2987828
9

Leute, die dies speziell mit LVM-Snapshots tun möchten , mögen vielleicht mein lvmsync- Tool, das die Liste der geänderten Blöcke in einem Snapshot liest und nur diese Änderungen sendet.

womble
quelle
6

Werfen Sie einen Blick auf Zumastor Linux Storage Project , das ein "Snapshot" -Sicherungsprogramm mit binärem "rsync" über das Tool " ddsnap " implementiert .

Von der Manpage:

ddsnap bietet eine Block-Device-Replikation mit einer Block-Level-Snapshot-Funktion, mit der mehrere Snapshots gleichzeitig effizient gespeichert werden können. ddsnap kann eine Liste von Snapshot-Chunks erstellen, die sich zwischen zwei Snapshots unterscheiden, und diese Differenz dann über die Leitung senden. Schreiben Sie auf einem Downstream-Server die aktualisierten Daten auf ein Snapshot-Block-Gerät.

rkthkr
quelle
Ah, das scheint genau das zu sein, wonach ich gesucht habe, danke.
David Hicks
Der Link zum Zumastor-Projekt ist veraltet, ich denke, das ist der richtige: shapor.com/zumastor.org
Martin
2

Es gibt ein Python-Skript namens blocksync, mit dem auf einfache Weise zwei Block-Geräte über ein Netzwerk via ssh synchronisiert werden können, wobei nur die Änderungen übertragen werden.

  • Kopieren Sie blocksync.py in das Ausgangsverzeichnis auf dem Remote-Host
  • Stellen Sie sicher, dass Ihr Remote-Benutzer entweder sudo oder root ist
  • Stellen Sie sicher, dass Ihr lokaler Benutzer (root?) Das Quellgerät & ssh auf dem Remote-Host lesen kann
  • Aufrufen: python blocksync.py /dev/source user@remotehost /dev/dest

Ich habe es kürzlich gehackt, um es zu bereinigen und so zu ändern, dass derselbe schnelle Prüfsummenalgorithmus wie bei rsync ( Adler-32 ) verwendet wird.

rcoup
quelle
1
Ich benutze es, funktioniert gut. Beachten Sie, dass es eine geänderte Version gibt , die eine mögliche Ursache für Korruption behebt und einen zuverlässigeren Hash verwendet.
cmc
1

Wenn Sie versuchen, die Menge an freiem Speicherplatz zu minimieren, die Sie mit einer Ebene über das Kabel senden würden dd, können Sie ihn dann nicht einfach an gzip leiten, bevor Sie ihn an ssh leiten?

zB dd if = / dev / xenVG / SERVER001OS | gzip | ssh administrator @ backupserver "dd von = / mnt / largeDisk / SERVER001OS.img.gz"

Ophidian
quelle
Es würde die benötigte Bandbreite etwas reduzieren, aber wir haben 60 und 100 GB Festplatten-Images und selbst mit gzip würde es zu lange dauern.
David Hicks
@Ophidian, du solltest wissen, dass SSH die Komprimierung intern handhabt, es gibt eine Option.
Poige
1

Beachten Sie jedoch, dass die Leistung eines Systems mit LVM-Snapshots proportional zur Anzahl der Snapshots ist.

Zum Beispiel Mysql-Performance mit lvm-Snapshots

James
quelle
Tatsächlich bestand meine anfängliche Lösung darin, einfach einen täglichen Snapshot zu erstellen, dann einen Unterschied zum Snapshot des vorherigen Tages zu machen und ihn auf den Backup-Server zu übertragen. Ich war am meisten verärgert, als ich herausfand, dass es nicht so einfach sein würde.
David Hicks
Das mag bei LVM Thin Snapshots, die sehr unterschiedlich implementiert sind, nicht der Fall sein
Alex F
0

Zusätzlich zu der Antwort von David Herselman wird das folgende Skript mit einem lokalen Gerät synchronisiert:

perl -'MDigest::MD5 md5' -ne 'BEGIN{$/=\1024};print md5($_)' $dev2 |
  perl -'MDigest::MD5 md5' -ne 'BEGIN{$/=\1024};$b=md5($_);
    read STDIN,$a,16;if ($a eq $b) {print "s"} else {print "c" . $_}' $dev1 |
   perl -ne 'BEGIN{$/=\1} if ($_ eq"s") {$s++} else {if ($s) {
    seek STDOUT,$s*1024,1; $s=0}; read ARGV,$buf,1024; print $buf}' 1<> $dev2

Soweit ich weiß, wurden beide Skripte zuerst unter lists.samba.org veröffentlicht .

Martin
quelle
0

Dies ist eine alte Frage, aber niemand erwähnte zwei sehr nützliche Tools, um zwei Blockgeräte effizient zu synchronisieren:

Ich empfehle dringend, mit beiden Werkzeugen zu spielen und das zu wählen, das sich besser an Ihre beabsichtigte Verwendung anpasst.

Shodanshok
quelle
0

Nach einigen Jahren der Suche habe ich kürzlich ein Tool zum Synchronisieren von LVM-Snapshots zwischen Servern erstellt. Es ist so konzipiert, dass nur minimale E / A-Vorgänge ausgeführt werden und die Systeme ausgeführt werden können, während die Synchronisierung stattfindet.

Es ähnelt dem Senden / Empfangen von ZFS, indem es die Unterschiede zwischen LVM-Snapshots synchronisiert und Thin Provisioning verwendet, sodass die Leistung nur minimal beeinträchtigt wird.

Ich hätte gerne Feedback, also schauen Sie doch mal rein.

David B
quelle
-1

An diesem Skript mussten einige Verbesserungen vorgenommen werden:

  1. Zumindest auf meinem System sind die Perl-Puffer-Lesevorgänge 8k, verwenden Sie also die Blockgröße 8192.
  2. Autoflush, damit das lokale Ende nicht blockiert, bis der Remote-Ausgabepuffer voll ist.

ssh -i /root/.ssh/rsync_rsa $ remote "perl -'MDigest :: MD5 md5 '-ne' BEGIN {$ | = 1; \ $ / = \ 892}; print md5 (\ $ ) '$ dev2 | lzop -c "| lzop -dc | perl -'MDigest :: MD5 md5 '-ne' BEGIN {$ | = 1; $ / = \ 8192}; $ b = md5 ($ ); Lies STDIN, $ a, 16; if ($ a eq $ b) {print "s"} else {print "c". $ _} '$ dev1 | lzop -c | ssh -i /root/.ssh/rsync_rsa $ remote "lzop -dc |
perl -ne 'BEGIN {\ $ / = \ 1} if (\ $ _eq \" s \ ") {\ $ s ++} else {if (\ $ s) {suche STDOUT, \ $ s * 8192,1; \ $ s = 0}; lies ARGV, \ $ buf, 8192; drucke \ $ buf} '1 <> $ dev2 "

Mike Mestnik
quelle