Sincronizar instantâneos do LVM para o servidor de backup


22

Eu tenho várias máquinas virtuais Xen em execução em vários servidores Linux. Essas VMs armazenam suas imagens de disco nos volumes Linux LVM com nomes de dispositivos nas linhas de / dev / xenVG / SERVER001OS e assim por diante. Gostaria de fazer backups regulares dessas imagens de disco para poder restaurar as VMs, caso necessário (os dispositivos LVM já estão espelhados com DRBD entre duas máquinas físicas cada, apenas estou sendo paranóico aqui).

Como faço para fazer isso? Obviamente, o primeiro passo é capturar instantaneamente o dispositivo LVM, mas como transfiro dados para um servidor de backup da maneira mais eficiente possível? Eu poderia simplesmente copiar todo o dispositivo, algo como:

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

... mas isso exigiria muita largura de banda. Existe uma ferramenta semelhante ao rsync para sincronizar o conteúdo de blocos de disco inteiro entre servidores remotos? Algo como:

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

Se eu entender a página de manual do rsync corretamente, o comando acima não funcionará (funcionará?), Mas mostra o que estou buscando. Entendo que a opção --devices rsync é copiar os próprios dispositivos, não o conteúdo desses dispositivos. Fazer uma cópia local da imagem da VM antes de sincronizá-la com o servidor remoto não é uma opção, pois não há espaço em disco.

Existe um utilitário útil que pode sincronizar entre dispositivos de bloco e um arquivo de backup em um servidor remoto? Posso escrever um, se for preciso, mas uma solução existente seria melhor. Perdi uma opção rsync que faz isso por mim?

Respostas:



16

Embora existam patches de 'dispositivo de gravação' e 'dispositivo de cópia' para o RSync, eles só funcionam bem em imagens pequenas (1-2 GB). O RSync passará anos pesquisando blocos correspondentes em imagens maiores e é quase inútil para dispositivos / arquivos de 40 GB ou maiores.

Usamos o seguinte para realizar uma comparação de soma de verificação por 1 MB e, em seguida, basta copiar o conteúdo, se não corresponder. Usamos isso para fazer backup de servidores em um host virtual nos EUA para um sistema de backup no Reino Unido, pela Internet pública. Muito pouca atividade na CPU e desempenho no snapshot ocorrem somente após o horário:

Crie um instantâneo:

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

Semeadura inicial:

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

Backup noturno incremental (envia apenas blocos alterados):

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"

Remova o instantâneo:

lvremove -f company-exchange-snap1

Eu estava com medo no começo, mas depois tentei e realmente funciona.
Martin

Por que em read ARGV,$buf,1024vez de read STDIN,$buf,1024@ sysadmin1138? (Estou tentando responder a stackoverflow.com/q/22693823/2987828 e não entendo o ARGV aqui). Eu uso todos os dias a variante na pergunta stackoverflow.com/q/22693823/2987828 e funciona bem.
user2987828

1
veja perlmonks.org/bare/?node_id=492858, que diz que ARGV e STDIN são semelhantes, a menos que um nome de arquivo seja fornecido como argumento.
user2987828

9

As pessoas interessadas em fazer isso especificamente com os instantâneos do LVM podem gostar da minha ferramenta lvmsync , que lê a lista de blocos alterados em um instantâneo e envia apenas essas alterações.


6

Dê uma olhada no Zumastor Linux Storage Project, que implementa o backup "instantâneo" usando o binário "rsync" através da ferramenta ddsnap .

Na página de manual:

O ddsnap fornece replicação de dispositivo de bloco, dado um recurso de captura instantânea no nível do bloco capaz de armazenar várias capturas instantâneas simultâneas com eficiência. O ddsnap pode gerar uma lista de blocos de snapshots que diferem entre dois snapshots e depois enviar essa diferença pela conexão. Em um servidor downstream, grave os dados atualizados em um dispositivo de bloco com captura instantânea.


Ah, isso parece exatamente o tipo de coisa que eu estava procurando, obrigado.
David Hicks

O link para o projeto Zumastor está desatualizado, eu acho que isso é o correto: shapor.com/zumastor.org
Martin

2

Existe um script python chamado blocksync, que é uma maneira simples de sincronizar dois dispositivos de bloco em uma rede via ssh, transferindo apenas as alterações.

  • Copie blocksync.py para o diretório inicial no host remoto
  • Certifique-se de que seu usuário remoto possa sudo ou seja o próprio root
  • Verifique se o usuário local (root?) Pode ler o dispositivo de origem & ssh no host remoto
  • Invocar: python blocksync.py /dev/source user@remotehost /dev/dest

Eu o hackeei recentemente para limpá-lo e alterá-lo para usar o mesmo algoritmo de soma de verificação rápida que o rsync ( Adler-32 ).


1
Estou usando, funciona bem. Observe que há uma versão modificada que corrige uma possível fonte de corrupção e usa um hash mais confiável.
Cmc 8/13

1

Se você está tentando minimizar a quantidade de espaço vazio que enviaria através do fio com uma planície dd, não poderia simplesmente canalizá-lo para o gzip antes de enviá-lo para o ssh?

por exemplo, dd se = / dev / xenVG / SERVER001OS | gzip | ssh administrator @ backupserver "dd de = / mnt / largeDisk / SERVER001OS.img.gz"


Reduziria a largura de banda necessária um pouco, mas temos algumas imagens de disco de 60 e 100 GB e mesmo com o gzip isso levaria muito tempo.
David Hicks

@ Ophidian, você deve saber que o SSH lida com a compressão internamente, há uma opção.
31411 poige

1

Lembre-se de que o desempenho de um sistema que possui capturas instantâneas LVM é proporcional ao número de capturas instantâneas.

Por exemplo, desempenho do MySQL com instantâneos lvm


De fato - minha solução inicial envolveu simplesmente definir um instantâneo diário e depois fazer uma diferença com o instantâneo do dia anterior e enviá-lo para o servidor de backup. Fiquei muito irritado ao descobrir que não seria tão simples.
David Hicks

Isso pode não ser verdade com os snapshots finos do LVM, que são implementados de maneira muito diferente #
F Alex

0

Além da resposta de David Herselman - o seguinte script será sincronizado com um dispositivo 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

Até onde eu sei, os dois scripts foram postados pela primeira vez em lists.samba.org .


0

Essa é uma pergunta antiga, mas ninguém mencionou duas ferramentas muito úteis para sincronizar com eficiência dois dispositivos de bloco:

Eu sugiro fortemente que você jogue com as duas ferramentas e selecione o que melhor se adaptar ao uso pretendido.


0

Após pesquisar por vários anos, criei recentemente uma ferramenta para sincronizar instantâneos do LVM entre servidores. Ele foi projetado para usar o mínimo de IO e permitir que os sistemas funcionem enquanto a sincronização está acontecendo.

É semelhante ao envio / recebimento do ZFS, pois sincroniza as diferenças entre os instantâneos do LVM e usa o provisionamento dinâmico para que o impacto no desempenho seja mínimo.

Gostaria de feedback, então, por favor, dê uma olhada.


-1

Havia algumas eficiências a serem feitas nesse script:

  1. No meu sistema, pelo menos, as leituras do buffer perl são 8k, portanto, use o tamanho do bloco 8192.
  2. autoflush para que a extremidade local não bloqueie até que o buffer de saída remota esteja 'cheio', pois como estamos alimentando o lzop, o buffer parece inútil.

ssh -i /root/.ssh/rsync_rsa $ remote "perl -'MDigest :: MD5 md5 '-ne' BEGIN {$ | = 1; \ $ / = \ 892}; imprima md5 (\ $ ) '$ dev2 | lzop -c "| lzop -dc | perl -'MDigest :: MD5 md5 '-ne' BEGIN {$ | = 1; $ / = \ 8192}; $ b = md5 ($ ); leia 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 'COMEÇA {\ $ / = \ 1} if (\ $ _ eq \" s \ ") {\ $ s ++} else {if (\ $ s) {seek STDOUT, \ $ s * 8192,1; \ $ s = 0}; leia ARGV, \ $ buf, 8192; imprima \ $ buf} '1 <> $ dev2 "

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.