Sincronizza le istantanee LVM sul server di backup


22

Ho un numero di macchine virtuali Xen in esecuzione su un numero di server Linux. Queste macchine virtuali memorizzano le immagini dei loro dischi nei volumi LVM di Linux con i nomi dei dispositivi lungo le linee di / dev / xenVG / SERVER001OS e così via. Vorrei fare backup regolari di quelle immagini del disco in modo da poter ripristinare le macchine virtuali nel caso in cui sia necessario (i dispositivi LVM sono già specchiati con DRBD tra due macchine fisiche ciascuna, sono solo paranoico in più qui).

Come posso procedere? Ovviamente il primo passo è quello di creare un'istantanea del dispositivo LVM, ma come posso quindi trasferire i dati su un server di backup nel modo più efficiente possibile? Potrei semplicemente copiare l'intero dispositivo, qualcosa sulla falsariga di:

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

... ma ciò richiederebbe molta larghezza di banda. Esiste uno strumento simile a rsync per sincronizzare i contenuti di interi blocchi di dischi tra server remoti? Qualcosa di simile a:

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

Se capisco correttamente la pagina man di rsync, il comando sopra non funzionerà (funzionerà?), Ma mostra a cosa sto puntando. Comprendo che l'opzione --devices rsync è quella di copiare i dispositivi stessi, non il contenuto di tali dispositivi. Fare una copia locale dell'immagine VM prima di sincronizzarla con il server remoto non è un'opzione in quanto non c'è spazio su disco.

Esiste una pratica utility in grado di sincronizzare tra i dispositivi a blocchi e un file di backup su un server remoto? Posso scriverne uno se devo, ma una soluzione esistente sarebbe migliore. Ho perso un'opzione rsync che fa questo per me?

Risposte:



16

Sebbene ci siano patch "write-device" e "copy-device" per RSync, funzionano bene solo su piccole immagini (1-2 GB). RSync impiegherà anni a cercare blocchi corrispondenti su immagini più grandi ed è quasi inutile di dispositivi / file da 40 GB o più grandi.

Usiamo quanto segue per eseguire un confronto di checksum per 1 MB e quindi semplicemente copiare il contenuto se non corrisponde. Lo usiamo per eseguire il backup dei server su un host virtuale negli Stati Uniti su un sistema di backup nel Regno Unito, tramite Internet pubblico. L'attività della CPU e le prestazioni dell'istantanea sono molto ridotte solo dopo ore:

Crea istantanea:

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='root@backup.company.co.za';

Semina iniziale:

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

Backup notturno incrementale (invia solo blocchi modificati):

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"

Rimuovi istantanea:

lvremove -f company-exchange-snap1

All'inizio ero spaventato ma poi l'ho provato e funziona davvero.
Martin,

Perché read ARGV,$buf,1024invece di read STDIN,$buf,1024@ sysadmin1138? (Sto cercando di rispondere alle stackoverflow.com/q/22693823/2987828 e non fare capire ARGV qui). Uso quotidianamente la variante nella domanda stackoverflow.com/q/22693823/2987828 e funziona bene.
user2987828

1
vedere perlmonks.org/bare/?node_id=492858 che afferma che ARGV e STDIN sono simili a meno che non venga fornito un nome file come argomento.
user2987828

9

Le persone interessate a farlo specificamente con le istantanee LVM potrebbero apprezzare il mio strumento lvmsync , che legge l'elenco dei blocchi modificati in un'istantanea e invia solo quelle modifiche.


6

Dai un'occhiata a Zumastor Linux Storage Project implementa il backup "snapshot" usando "rsync" binario tramite lo strumento ddsnap .

Dalla pagina man:

ddsnap fornisce la replica del dispositivo a blocchi data una funzione di istantanea a livello di blocco in grado di contenere in modo efficiente più istantanee simultanee. ddsnap può generare un elenco di blocchi di istantanee che differiscono tra due istantanee, quindi inviare tale differenza sul filo. Su un server downstream, scrivere i dati aggiornati su un dispositivo di blocco snapshot.


Ah, sembra proprio il tipo di cosa che stavo cercando, grazie.
David Hicks

Il link al progetto Zumastor è obsoleto, suppongo che sia quello corretto: shapor.com/zumastor.org
Martin

2

C'è uno script Python chiamato BlockSync che è un modo semplice per sincronizzare due dispositivi a blocchi su una rete tramite SSH, trasferendo solo le modifiche.

  • Copia blocksync.py nella home directory sull'host remoto
  • Assicurati che il tuo utente remoto sia sudo o sia root stesso
  • Assicurarsi che l'utente locale (root?) Possa leggere il dispositivo sorgente e ssh sull'host remoto
  • Invocare: python blocksync.py /dev/source user@remotehost /dev/dest

Di recente l'ho hackerato per ripulirlo e cambiarlo per utilizzare lo stesso algoritmo di checksum veloce di rsync ( Adler-32 ).


1
Lo sto usando, funziona benissimo. Nota che esiste una versione modificata che corregge una possibile fonte di corruzione e utilizza un hash più affidabile.
cmc

1

Se stai cercando di ridurre al minimo la quantità di spazio vuoto che invierai attraverso il filo con una semplice dd, non potresti semplicemente collegarlo a gzip prima di inviarlo a ssh?

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


Avrebbe ridotto un po 'la larghezza di banda necessaria, ma abbiamo circa 60 e 100 GB di immagini del disco e anche con gzip ci vorrebbe troppo tempo.
David Hicks,

@Ophidian, dovresti sapere che SSH gestisce la compressione internamente, c'è un'opzione.
poige,

1

Basta fare attenzione che le prestazioni di un sistema con snapshot LVM sono proporzionali al numero di snapshot.

Ad esempio le prestazioni di Mysql con le istantanee di lvm


In effetti, la mia soluzione iniziale consisteva semplicemente nell'impostare un'istantanea giornaliera, quindi fare una diff con l'istantanea del giorno precedente e trasferirla sul server di backup. Ero molto rattristato nello scoprire che non sarebbe stato così semplice.
David Hicks,

Questo potrebbe non essere vero con le snapshot LVM che sono implementate in modo molto diverso
Alex F,

0

Oltre alla risposta di David Herselman, il seguente script si sincronizzerà con un dispositivo locale:

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

Per quanto ne so, entrambi gli script sono stati pubblicati per la prima volta su lists.samba.org .


0

Questa è una vecchia domanda, ma nessuno ha menzionato due strumenti molto utili per sincronizzare in modo efficiente due dispositivi a blocchi:

Consiglio vivamente di giocare con entrambi gli strumenti e di selezionare quello che meglio si adatta all'utilizzo previsto.


0

Dopo aver cercato per diversi anni, di recente ho creato uno strumento per sincronizzare le istantanee LVM tra i server. È progettato per utilizzare un IO minimo e consentire l'esecuzione dei sistemi durante la sincronizzazione.

È simile all'invio / ricezione di ZFS in quanto sincronizza le differenze tra le istantanee LVM e utilizza il thin provisioning in modo che l'impatto sulle prestazioni sia minimo.

Vorrei un feedback, quindi per favore dai un'occhiata.


-1

C'erano alcune efficienze da apportare a questo script:

  1. Almeno sul mio sistema, le letture del buffer perl sono 8k, quindi utilizzare la dimensione del blocco 8192.
  2. autoflush in modo che l'estremità locale non si blocchi fino a quando il buffer di output remoto è "pieno", poiché stiamo alimentando lzop il buffering sembra inutile.

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.