como unidirecional espelhar um conjunto zfs inteiro para outro conjunto zfs

9

Eu tenho um pool zfs contendo vários zvols e conjuntos de dados dos quais alguns também são aninhados. Todos os conjuntos de dados e zvols são periodicamente instantâneos por zfs-auto-snapshot. Todos os conjuntos de dados e zvols também possuem alguns instantâneos criados manualmente.

Configurei um pool remoto no qual, devido à falta de tempo, a cópia inicial da rede local de alta velocidade via zfs send -R não foi concluída (alguns conjuntos de dados estão ausentes, alguns conjuntos de dados possuem snapshots desatualizados ou ausentes).

Agora, o pool é fisicamente remoto em uma conexão de baixa velocidade e eu preciso sincronizar periodicamente o pool remoto com o pool local, ou seja, os dados presentes no pool local devem ser copiados para o pool remoto, os dados do pool local devem ser excluídos do pool remoto pool, e os dados presentes no pool remoto, mas não no pool local, devem ser excluídos do pool remoto, por dados que significam 'zvols', 'datasets' ou 'snapshots'.

Se eu estivesse fazendo isso entre dois sistemas de arquivos regulares usando rsync, seria "-axPHAX --delete" (é o que eu realmente faço para fazer o backup de alguns sistemas).

Como configuro uma tarefa de sincronização para que o pool remoto zvols & conjuntos de dados (incluindo os snapshots) podem estar em sincronia com zvols locais, conjuntos de dados e snapshots?

Eu gostaria de evitar a transferência através do ssh, devido ao baixo desempenho de rendimento do ssh; Eu preferiria mbuffer ou iscsi.

    
por Costin Gușă 16.02.2016 / 19:34

4 respostas

5

Pessoalmente, gostaria de criar uma lista de zvols, conjuntos de dados, etc., no servidor remoto que não tenha instantâneos atualizados e, em seguida, exiba esses instantâneos com zfs send , mesmo que isso consuma tempo e consuma muita largura de banda.

Então eu poderia continuar usando zfs send a partir de então e não ter que reinventar a roda escrevendo meu próprio código de sincronização. rsync é bom para sistemas de arquivos antigos, mas zfs send é muito melhor para zfs - ele sabe exatamente quais blocos foram alterados no instantâneo e envia somente eles, enquanto o rsync tem para comparar arquivos individuais e / ou registros de data e hora entre servidores locais e remotos. O mesmo se aplica a btrfs send para pools btrfs.

Se você tiver apenas um pequeno número de instantâneos que precisam ser atualizados, isso pode ser feito manualmente. Caso contrário, para fazer isso automaticamente, você precisa de uma lista dos instantâneos locais mais recentes vs instantâneos remotos e um script para comparar versões e, em seguida, zfs send instantâneos locais que estão desatualizados no servidor do rmeote.

Isso será suficiente se você se importar apenas com o último snapshot de cada conjunto de dados. Se você se preocupa com todos os instantâneos anteriores, obviamente seu script terá que lidar com eles também ... e isso se torna muito mais complicado. Em alguns casos, pode ser necessário reverter o servidor remoto para que você possa reenviar os instantâneos intermediários / ausentes.

Se você quiser uma conexão segura com o servidor remoto, você realmente tem pouca escolha a não ser usar ssh - ou talvez configurar um túnel com openvpn ou algo assim e usar netcat .

    
por 16.02.2016 / 21:12
4

Disclaimer: Como eu nunca usei o zvols, não posso dizer se eles são diferentes na replicação do que sistemas de arquivos normais ou snapshots. Eu suponho que eles são, mas não acredite em mim.

A sua pergunta é na verdade várias perguntas, tento respondê-las separadamente:

Como replicar / espelhar o conjunto completo para o local remoto

Você precisa dividir a tarefa em duas partes: primeiro, a replicação inicial deve ser concluída, depois a replicação incremental é possível, contanto que você não mexa com os instantâneos de replicação . Para habilitar a replicação incremental, você precisa preservar os últimos instantâneos de replicação, tudo antes que possa ser excluído. Se você excluir o instantâneo anterior, zfs recv irá reclamar e abortar a replicação. Neste caso você tem que começar tudo de novo, então tente não fazer isso.

Se você só precisa das opções corretas, elas são:

  • %código%:
    • zfs send : envia tudo sob o conjunto de dados ou conjunto de dados (a replicação recursiva, necessária o tempo todo, inclui -R ). Além disso, ao receber, todos os instantâneos de origem excluídos são excluídos no destino.
    • -p : inclui todos os instantâneos intermediários entre o último instantâneo de replicação e o instantâneo de replicação atual (necessário apenas com envios incrementais)
  • %código%:
    • -I : expanda o pool de destino, incluindo a exclusão de conjuntos de dados existentes que são excluídos na origem
    • zfs recv : descarte o nome do conjunto de origem e substitua-o pelo nome do conjunto de destino (o restante dos caminhos do sistema de arquivos será preservado e, se necessário, também criado)
    • -F : não monte o sistema de arquivos no destino

Se você preferir um exemplo completo, aqui está um pequeno script:

#!/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

Use algo mais rápido que o SSH

Se você tiver uma conexão suficientemente segura, por exemplo, um túnel IPSec ou OpenVPN e uma VLAN separada que exista apenas entre remetente e destinatário, poderá alternar de SSH para alternativas não criptografadas, como mbuffer como é descrito aqui , ou você pode usar o SSH com criptografia fraca / sem criptografia e desativada, que é detalhado aqui . Também houve um site sobre a recombilação do SSH para ser muito mais rápido, mas infelizmente não me lembro da URL - vou editá-lo mais tarde se eu encontrá-lo.

Para conjuntos de dados muito grandes e conexões lentas, também pode ser útil para a primeira transmissão via disco rígido (use disco criptografado para armazenar o zpool e transmiti-lo em um pacote lacrado via correio, correio ou pessoalmente). Como o método de transmissão não importa para send / recv, você pode canalizar tudo para o disco, exportar o pool, enviar o disco para seu destino, importar o pool e então transmitir todos os envios incrementais via SSH.

O problema com instantâneos confusos

Como afirmado anteriormente, se você excluir / modificar seus instantâneos de replicação, receberá a mensagem de erro

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

, o que significa que seu comando estava errado ou que você está em um estado inconsistente, no qual você deve remover os instantâneos e começar tudo de novo.

Isso tem várias implicações negativas:

  1. Você não pode excluir um instantâneo de replicação até que o novo instantâneo de replicação seja transferido com êxito. Como esses snapshots de replicação incluem o estado de todos os outros snapshots (antigos), o espaço vazio de arquivos excluídos e os snapshots só serão recuperados se a replicação for concluída. Isso pode levar a problemas de espaço temporários ou permanentes em seu pool, que só podem ser resolvidos reiniciando ou concluindo o procedimento de replicação completo.
  2. Você terá muitas capturas instantâneas adicionais, o que desacelera o comando list (exceto no Oracle Solaris 11, onde isso foi corrigido).
  3. Talvez seja necessário proteger os instantâneos contra a remoção (acidental), exceto pelo próprio script.

Existe uma solução possível para esses problemas, mas eu mesmo não tentei. Você pode usar o -d , um novo recurso do OpenSolaris / illumos criado especificamente para essa tarefa. Isso livraria você do gerenciamento de instantâneos. A única desvantagem é que, no momento, ele só funciona para conjuntos de dados únicos, não recursivamente. Você teria que salvar uma lista de todos os seus conjuntos de dados antigos e novos e, em seguida, fazer um loop sobre eles, marcando, enviando e recebendo-os e atualizando a lista (ou banco de dados pequeno, se preferir).

Se você tentar a rota do favorito, eu estaria interessado em saber como isso funcionou para você!

    
por 24.02.2016 / 14:33
1

Dê uma olhada no 'zrepl', no FreeBSD, que pode tornar sua vida, e qualquer um, muito mais fácil. Foi apresentado há alguns dias durante o BSDCan2018 em Ottawa. Parece promissor e pode ser uma solução para seus problemas

    
por 13.06.2018 / 10:55
0

O zrep é uma ótima solução tudo em um, e tem documentação + ganchos sobre como obter transferências mais rápidas do que apenas transferências simples de SSH

link

também é crossplatform: suportado em linux, freebsd e solaris / illumos

    
por 07.09.2018 / 19:09