como espelhar unidirecionalmente um pool zfs inteiro para outro pool zfs

15

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

Eu configurei um pool remoto no qual, devido à falta de tempo, a cópia inicial pela 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 têm snapshots desatualizados ou ausentes).

Agora, o pool é fisicamente remoto por uma conexão de velocidade lenta e preciso sincronizar periodicamente o pool remoto com o pool local, o que significa que os dados presentes no pool local devem ser copiados para o pool remoto, os dados retirados do pool local devem ser excluídos do pool remoto 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 comuns usando o rsync, seria "-axPHAX --delete" (é o que eu realmente faço para fazer backup de alguns sistemas).

Como configuro uma tarefa de sincronização para que os zvols e conjuntos de dados do pool remoto (incluindo seus snapshots) possam estar sincronizados com os zvols, conjuntos de dados e snapshots locais?

Eu gostaria de evitar a transferência pelo ssh, devido ao baixo desempenho do throughput do ssh; Prefiro mbuffer ou iscsi.

Costin Gușă
fonte
Como você fez sua inicial zfs send -R ...? Se você canalizou a saída via ssh, desabilitou os caracteres de escape zfs send -R ... | ssh -e none ...?
Andrew Henle
Além disso - você precisa garantir que sua conexão lenta tenha largura de banda suficiente para manter a cópia remota atualizada. Se você estiver obtendo mais alterações no sistema local do que pode enviar ao sistema remoto, nunca poderá manter a cópia remota atualizada. Pegue um fluxo de replicação incremental do zfs e salve-o em um arquivo. Se o arquivo for maior que a quantidade de dados que você pode enviar para o site remoto na quantidade de tempo entre os instantâneos, você nunca acompanhará. zfs send -R -i pool@snap1 pool@snap2 | gzip --fast > /output/file.gz
Andrew Henle
Você também pode tentar usar esse script para fazê-lo automaticamente: github.com/psy0rz/zfs_autobackup/blob/master/README.md
edwin eefting

Respostas:

10

Isenção de responsabilidade: como nunca usei zvols, não posso dizer se eles são diferentes na replicação do que os sistemas de arquivos ou instantâneos normais. Suponho que sim, mas não aceite minha palavra.


Sua pergunta é realmente várias perguntas, tento respondê-las separadamente:

Como replicar / espelhar o pool completo para um local remoto

Você precisa dividir a tarefa em duas partes: primeiro, a replicação inicial precisa estar completa; depois, a replicação incremental é possível, desde que você não mexa nos seus instantâneos de replicação . Para habilitar a replicação incremental, é necessário preservar os últimos instantâneos de replicação, tudo antes que possa ser excluído. Se você excluir o instantâneo anterior, zfs recvirá reclamar e abortar a replicação. Nesse caso, você precisa começar tudo de novo, portanto, tente não fazer isso.

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

  • zfs send:
    • -R: envie tudo sob o conjunto ou conjunto de dados fornecido (a replicação recursiva, necessária o tempo todo, inclui -p). Além disso, ao receber, todos os instantâneos de origem excluídos são excluídos no destino.
    • -I: inclua 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)
  • zfs recv:
    • -F: expanda o pool de destino, incluindo a exclusão de conjuntos de dados existentes que são excluídos na origem
    • -d: 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 será criado)
    • -u: 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 SSH

Se você possui uma conexão suficientemente segura, por exemplo, túnel IPSec ou OpenVPN e uma VLAN separada que existe apenas entre remetente e receptor, você pode alternar do SSH para alternativas não criptografadas como mbuffer, conforme descrito aqui , ou usar o SSH com criptografia fraca / sem criptografia e compactação desativada, que é detalhada aqui . Havia também um site sobre a recompilação do SSH para ser muito mais rápido, mas infelizmente não lembro a URL - editarei mais tarde, se a encontrar.

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 o disco criptografado para armazenar o zpool e transmiti-lo em um pacote selado por correio, correio ou pessoalmente). Como o método de transmissão não importa para envio / recv, você pode canalizar tudo para o disco, exportar o pool, enviar o disco para seu destino, importar o pool e 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 você está em um estado inconsistente no qual 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 tenha sido transferido com êxito. Como esses instantâneos de replicação incluem o estado de todos os outros instantâneos (mais antigos), o espaço vazio dos arquivos e instantâneos excluídos será recuperado apenas se a replicação terminar. Isso pode levar a problemas de espaço temporário ou permanente no pool, que você só pode corrigir reiniciando ou concluindo o procedimento de replicação completo.
  2. Você terá muitos instantâneos adicionais, o que atrasa o comando list (exceto no Oracle Solaris 11, onde isso foi corrigido).
  3. Pode ser 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 zfs bookmarkum novo recurso do OpenSolaris / illumos criado especificamente para esta tarefa. Isso liberaria você do gerenciamento de instantâneos. A única desvantagem é que, atualmente, ele funciona apenas para conjuntos de dados únicos, não recursivamente. Você precisaria salvar uma lista de todos os seus conjuntos de dados antigos e novos e, em seguida, fazer um loop sobre eles, marcar, enviar e receber e, em seguida, atualizar a lista (ou banco de dados pequeno, se preferir).

Se você tentar a rota dos favoritos, gostaria de saber como funcionou para você!

user121391
fonte
muito obrigado por esta resposta detalhada. eu sou apenas send..recebendo a zpool.
Jitter #
1
bom roteiro. Eu adicionaria -d 1a ambos os zfs listcomandos para limitar a profundidade da pesquisa (não há necessidade de pesquisar abaixo do nome do pool). Isso evita longos atrasos em conjuntos com muitos instantâneos (por exemplo, meu pool de "backup" possui 320000 instantâneos e zfs list -r -t snapshot backupleva 13 minutos para ser executado. Leva apenas 0,06 segundos com -d 1). O zfs destroycomando no loop for precisa da -ropção de excluir recursivamente todos os snapshots com o mesmo snapname.
cas
5

Pessoalmente, eu faria uma lista de zvols, conjuntos de dados etc. no servidor remoto que não possui instantâneos atualizados e os atualizaria zfs send, mesmo que isso consuma tempo e use muito de largura de banda.

Então eu poderia continuar usando a zfs sendpartir de então e não precisar reinventar a roda escrevendo meu próprio código de sincronização. rsyncé bom para sistemas de arquivos mais antigos, mas zfs sendé muito melhor para zfs - ele sabe exatamente quais blocos foram alterados no snapshot e os envia apenas , enquanto o rsync precisa comparar arquivos individuais e / ou registros de data e hora entre servidores locais e remotos. o mesmo se aplica aos btrfs sendconjuntos btrfs.

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

Isso será suficiente se você se importar apenas com o instantâneo mais recente para cada conjunto de dados. Se você se preocupa com todos os instantâneos anteriores, obviamente seu script precisará lidar com eles também .... e isso se torna MUITO mais complicado. Em alguns casos, pode ser necessário retroceder no servidor remoto para poder reenviar os instantâneos intermediários / ausentes.

Se você deseja uma conexão segura com o servidor remoto, você realmente tem poucas opções a não ser usar ssh- ou talvez montar um túnel openvpnou algo assim e usar netcat.

cas
fonte
Que tal usar o Zrep? bolthole.com/solaris/zrep
Xdg
não sei, nunca usei. parece que seria uma boa resposta, se alguém fizesse uma pequena pesquisa e teste e a escrevesse (isso é uma dica).
cas 14/01
Eu testei no Ubuntu (ZFS no linux) e não estava funcionando em conjuntos de dados mais profundos (tank / algo / outra pessoa). Eu estava usando esta porta para fazer o shell - link . A bandeira recursiva export ZREP_R=-Rnão estava funcionando. :(
XDG
1

Dê uma olhada no `zrepl ', no FreeBSD, o que poderia tornar sua vida e qualquer outra pessoa 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

fd0
fonte
A pergunta da pergunta é: "Como configuro uma tarefa de sincronização para que os zvols e conjuntos de dados do pool remoto (incluindo seus instantâneos) possam estar sincronizados com os zvols, conjuntos de dados e instantâneos locais?"
Jeff Schaller
0

O zrep é uma boa solução tudo-em-um, E possui documentação + ganchos sobre como obter transferências mais rápidas do que apenas transferências SSH simples

https://github.com/bolthole/zrep

também é multiplataforma: suportada em linux, freebsd e solaris / illumos

Philip Brown
fonte
1
A pergunta da pergunta é: "Como configuro uma tarefa de sincronização para que os zvols e conjuntos de dados do pool remoto (incluindo seus instantâneos) possam estar sincronizados com os zvols, conjuntos de dados e instantâneos locais?"
Jeff Schaller
Jeff, você está sugerindo que a melhor "resposta" seria cortar e colar pedaços da documentação do zrep, em vez de apenas dar uma referência ao zrep?
Philip Brown
1
Não sei qual seria a melhor resposta, mas um link para o software não é uma solução. Já foi mencionado, de fato. A pergunta é: "Como configuro uma tarefa de sincronização para que os zvols e conjuntos de dados do pool remoto (incluindo seus instantâneos) possam estar sincronizados com os zvols, conjuntos de dados e instantâneos locais?"
Jeff Schaller
Sim, eis a questão. No entanto, para realizar bem a tarefa, é necessário muito mais do que uma pequena anotação em uma página da Web aqui. É por isso que o zrep é um shellscript de 2000 linhas. Mesmo se fosse necessário remover todas as partes que o problema original nunca precisava, ainda haveria algumas centenas de linhas de script necessárias para isso.
Philip Brown