Synchroniser les instantanés LVM avec le serveur de sauvegarde

22

J'ai un certain nombre de machines virtuelles Xen exécutées sur un certain nombre de serveurs Linux. Ces machines virtuelles stockent leurs images de disque dans des volumes Linux LVM avec des noms de périphériques tels que / dev / xenVG / SERVER001OS, etc. J'aimerais faire des sauvegardes régulières de ces images de disque afin que je puisse restaurer les machines virtuelles au cas où nous en aurions besoin (les périphériques LVM sont déjà mis en miroir avec DRBD entre deux machines physiques chacune, je suis juste paranoïaque supplémentaire ici).

Comment dois-je procéder? Évidemment, la première étape consiste à prendre un instantané du périphérique LVM, mais comment puis-je transférer les données vers un serveur de sauvegarde de la manière la plus efficace possible? Je pourrais simplement copier l'ensemble de l'appareil, quelque chose comme:

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

... mais cela prendrait beaucoup de bande passante. Existe-t-il un outil de type rsync pour synchroniser le contenu de blocs de disques entiers entre des serveurs distants? Quelque chose comme:

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

Si je comprends correctement la page de manuel de rsync, la commande ci-dessus ne fonctionnera pas réellement (le sera-t-elle?), Mais elle montre ce que je vise. Je comprends que l'option --devices rsync consiste à copier les périphériques eux-mêmes, et non le contenu de ces périphériques. Faire une copie locale de l'image de la machine virtuelle avant de la synchroniser avec le serveur distant n'est pas une option car il n'y a pas d'espace disque.

Existe-t-il un utilitaire pratique qui peut synchroniser entre les périphériques de bloc et un fichier de sauvegarde sur un serveur distant? Je peux en écrire un si je le dois, mais une solution existante serait mieux. Ai-je manqué une option rsync qui fait cela pour moi?

David Hicks
la source

Réponses:

12

Il manque cette fonctionnalité à rsync standard, mais il y a un correctif pour cela dans l'archive rsync-patches (copy-devices.diff) qui peut être téléchargé depuis http://rsync.samba.org/ftp/rsync/ Après avoir appliqué et recompilé , vous pouvez rsync les périphériques avec l'option --copy-devices.

Balázs Pozsár
la source
si votre cible est un appareil, le patch se trouve ici: bugzilla.redhat.com/show_bug.cgi?id=1193654
Jason Pyeron
16

Bien qu'il existe des correctifs «périphérique d'écriture» et «périphérique de copie» pour RSync, ils ne fonctionnent bien que sur les petites images (1 à 2 Go). RSync passera des heures à chercher des blocs correspondants sur des images plus grandes et il est presque inutile de 40 Go ou de périphériques / fichiers plus grands.

Nous utilisons ce qui suit pour effectuer une comparaison de somme de contrôle par 1 Mo, puis copions simplement le contenu s'il ne correspond pas. Nous l'utilisons pour sauvegarder des serveurs sur un hôte virtuel aux États-Unis vers un système de sauvegarde au Royaume-Uni, sur Internet public. Très peu d'activité du processeur et de performances de capture instantanée ne se produisent qu'après des heures:

Créer un instantané:

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]';

Ensemencement initial:

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

Sauvegarde incrémentielle nocturne (envoie uniquement les blocs modifiés):

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"

Supprimer l'instantané:

lvremove -f company-exchange-snap1
sysadmin1138
la source
J'ai eu peur au début, mais j'ai ensuite essayé et ça fonctionne vraiment.
Martin
Pourquoi read ARGV,$buf,1024au lieu de read STDIN,$buf,1024, @ sysadmin1138? (J'essaie de répondre à stackoverflow.com/q/22693823/2987828 et je ne comprends pas ARGV ici). J'utilise tous les jours la variante dans la question stackoverflow.com/q/22693823/2987828 et ça marche bien.
user2987828
1
voir perlmonks.org/bare/?node_id=492858 qui dit que ARGV et STDIN sont similaires à moins qu'un nom de fichier ne soit donné comme argument.
user2987828
9

Les personnes intéressées à le faire spécifiquement avec des instantanés LVM pourraient aimer mon outil lvmsync , qui lit la liste des blocs modifiés dans un instantané et envoie uniquement ces modifications.

womble
la source
6

Jetez un oeil à Zumastor Linux Storage Project, il implémente la sauvegarde "snapshot" en utilisant "rsync" binaire via l' outil ddsnap .

Depuis la page de manuel:

ddsnap fournit une réplication de périphérique de bloc grâce à une fonction d'instantané au niveau du bloc capable de contenir efficacement plusieurs instantanés simultanés. ddsnap peut générer une liste de blocs de snapshots qui diffèrent entre deux snapshots, puis envoyer cette différence sur le câble. Sur un serveur en aval, écrivez les données mises à jour sur un périphérique de bloc instantané.

rkthkr
la source
Ah, cela ressemble exactement au genre de chose que je cherchais, merci.
David Hicks
Le lien vers le projet Zumastor est obsolète, je suppose que c'est le bon: shapor.com/zumastor.org
Martin
2

Il existe un script python appelé blocksync qui est un moyen simple de synchroniser deux périphériques de bloc sur un réseau via ssh, en ne transférant que les modifications.

  • Copiez blocksync.py dans le répertoire personnel de l'hôte distant
  • Assurez-vous que votre utilisateur distant peut soit sudo, soit root lui-même
  • Assurez-vous que votre utilisateur local (root?) Peut lire le périphérique source et ssh sur l'hôte distant
  • Invoquer: python blocksync.py /dev/source user@remotehost /dev/dest

Je l'ai récemment piraté pour le nettoyer et le changer pour utiliser le même algorithme de somme de contrôle rapide que rsync ( Adler-32 ).

rcoup
la source
1
Je l'utilise, ça marche bien. Notez qu'il existe une version modifiée qui corrige une source possible de corruption et utilise un hachage plus fiable.
cmc
1

Si vous essayez de minimiser l'espace vide que vous enverriez à travers le fil avec une plaine dd, ne pourriez-vous pas simplement le diriger vers gzip avant de le diriger vers ssh?

par exemple dd if = / dev / xenVG / SERVER001OS | gzip | administrateur ssh @ backupserver "dd of = / mnt / largeDisk / SERVER001OS.img.gz"

Ophidian
la source
Cela réduirait un peu la bande passante nécessaire, mais nous avons des images de disque de 60 et 100 Go et même avec gzip, cela prendrait trop de temps.
David Hicks
@Ophidian, vous devez savoir que SSH gère la compression en interne, il y a une option.
poige
1

Gardez simplement à l'esprit que les performances d'un système doté d'instantanés LVM sont proportionnelles au nombre d'instantanés.

Par exemple, les performances de Mysql avec des instantanés lvm

James
la source
En effet - ma solution initiale consistait simplement à définir un instantané quotidien, puis à faire un diff avec l'instantané de la veille et à le sauvegarder sur le serveur de sauvegarde. J'étais le plus irrité de découvrir que ce ne serait pas aussi simple.
David Hicks
Cela peut ne pas être vrai avec les instantanés minces LVM qui sont implémentés de manière très différente
Alex F
0

En plus de la réponse de David Herselman - le script suivant se synchronisera avec un appareil local:

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

Autant que je sache, les deux scripts ont d'abord été publiés sur lists.samba.org .

Martin
la source
0

C'est une vieille question, mais personne n'a mentionné deux outils très utiles pour synchroniser efficacement deux périphériques de bloc:

Je suggère fortement de jouer avec les deux outils et de sélectionner celui qui s'adapte le mieux à votre utilisation prévue.

shodanshok
la source
0

Après plusieurs années de recherche, j'ai récemment créé un outil de synchronisation des snapshots LVM entre serveurs. Il est conçu pour utiliser un minimum d'E / S et permettre aux systèmes de fonctionner pendant la synchronisation.

Il est similaire à l'envoi / réception ZFS en ce sens qu'il synchronise les différences entre les instantanés LVM et utilise un provisionnement fin afin que l'impact sur les performances soit minime.

J'aimerais avoir des commentaires, alors s'il vous plaît jetez un œil.

David B
la source
-1

Il y avait quelques efficacités à apporter à ce script:

  1. Sur mon système au moins, les lectures du tampon Perl sont de 8 Ko, utilisez donc la taille de bloc 8192.
  2. autoflush afin que l'extrémité locale ne se bloque pas tant que le tampon de sortie distant n'est pas plein, car nous alimentons lzop, le tampon semble inutile.

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 ($ ); lire 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) {chercher STDOUT, \ $ s * 8192,1; \ $ s = 0}; lire ARGV, \ $ buf, 8192; imprimer \ $ buf} '1 <> $ dev2 "

Mike Mestnik
la source