rsync para vários destinos usando a mesma lista de arquivos?

22

Gostaria de saber se é possível para o rsync copiar um diretório para vários destinos remotos de uma só vez, ou mesmo em paralelo. (não é necessário, mas seria útil.)

Normalmente, algo como o seguinte funcionaria perfeitamente:

$ rsync -Pav /junk user@host1:/backup
$ rsync -Pav /junk user@host2:/backup
$ rsync -Pav /junk user@host3:/backup

E se essa é a única opção, eu usarei isso. No entanto, o / junk está localizado em uma unidade lenta com poucos arquivos, e a reconstrução da lista de arquivos de aproximadamente 12.000 arquivos a cada vez é agonizantemente lenta (~ 5 minutos) em comparação com a transferência / atualização real. É possível fazer algo assim, para realizar a mesma coisa:

$ rsync -Pav /junk user@host1:/backup user@host2:/backup user@host3:/backup 

Obrigado por olhar!

Jessie
fonte

Respostas:

12

Aqui estão as informações da página de manual do rsync sobre o modo em lote.

MODO DE LOTE

O modo de lote pode ser usado para aplicar o mesmo conjunto de atualizações a muitos sistemas idênticos. Suponha que se tenha uma árvore que seja replicada em vários hosts. Agora, suponha que algumas alterações foram feitas nessa árvore de origem e essas alterações precisam ser propagadas para os outros hosts. Para fazer isso usando o modo em lote, o rsync é executado com a opção write-batch para aplicar as alterações feitas na árvore de origem em uma das árvores de destino. A opção write-batch faz com que o cliente rsync armazene em um "arquivo em lotes" todas as informações necessárias para repetir essa operação em outras árvores de destino idênticas.

A geração do arquivo em lote uma vez economiza a execução do status do arquivo, soma de verificação e geração de bloco de dados mais de uma vez ao atualizar várias árvores de destino. Os protocolos de transporte multicast podem ser usados ​​para transferir os arquivos de atualização em lote em paralelo para muitos hosts ao mesmo tempo, em vez de enviar os mesmos dados para cada host individualmente.

Para aplicar as alterações registradas em outra árvore de destino, execute rsync com a opção de lote de leitura, especificando o nome do mesmo arquivo em lotes e a árvore de destino. O Rsync atualiza a árvore de destino usando as informações armazenadas no arquivo em lotes.

Para sua conveniência, um arquivo de script também é criado quando a opção write-batch é usada: ele será nomeado da mesma forma que o arquivo em lote com ".sh" anexado. Este arquivo de script contém uma linha de comando adequada para atualizar uma árvore de destino usando o arquivo em lotes associado. Ele pode ser executado usando um shell Bourne (ou semelhante a Bourne), passando opcionalmente um nome de caminho de árvore de destino alternativo que é usado em vez do caminho de destino original. Isso é útil quando o caminho da árvore de destino no host atual difere daquele usado para criar o arquivo em lotes.

   Examples:

          $ rsync --write-batch=foo -a host:/source/dir/ /adest/dir/
          $ scp foo* remote:
          $ ssh remote ./foo.sh /bdest/dir/

          $ rsync --write-batch=foo -a /source/dir/ /adest/dir/
          $ ssh remote rsync --read-batch=- -a /bdest/dir/ <foo

Nestes exemplos, o rsync é usado para atualizar / adest / dir / de / source / dir / e as informações para repetir essa operação são armazenadas em "foo" e "foo.sh". O host "remoto" é atualizado com os dados em lote que entram no diretório / bdest / dir. As diferenças entre os dois exemplos revelam um pouco da flexibilidade que você tem na maneira de lidar com lotes:

  • O primeiro exemplo mostra que a cópia inicial não precisa ser local - você pode enviar ou enviar dados de / para um host remoto usando a sintaxe do shell remoto ou a sintaxe do daemon rsync, conforme desejado.

  • O primeiro exemplo usa o arquivo "foo.sh" criado para obter as opções certas de rsync ao executar o comando read-batch no host remoto.

  • O segundo exemplo lê os dados em lote via entrada padrão, para que o arquivo em lotes não precise ser copiado primeiro na máquina remota. Este exemplo evita o script foo.sh porque precisava usar uma opção --read-batch modificada, mas você poderia editar o arquivo de script se desejasse utilizá-lo (apenas certifique-se de que nenhuma outra opção esteja tentando usar o padrão entrada, como a opção "--exclude-from = -").

    Ressalvas:

    A opção de leitura em lote espera que a árvore de destino que está sendo atualizada seja idêntica à árvore de destino usada para criar o conjunto de arquivos de atualização em lote. Quando é encontrada uma diferença entre as árvores de destino, a atualização pode ser descartada com um aviso (se o arquivo já estiver atualizado) ou a atualização do arquivo pode ser tentada e, em seguida, se o arquivo falhar na verificação , a atualização descartada com um erro. Isso significa que deve ser seguro executar novamente uma operação de lote de leitura se o comando for interrompido. Se você deseja forçar a tentativa de atualização em lote sempre, independentemente do tamanho e data do arquivo, use a opção -I (ao ler o lote). Se ocorrer um erro, a árvore de destino provavelmente estará em um estado parcialmente atualizado. Nesse caso,

    A versão rsync usada em todos os destinos deve ser pelo menos tão nova quanto a usada para gerar o arquivo em lotes. O Rsync sofrerá um erro se a versão do protocolo no arquivo em lotes for muito nova para o rsync de leitura em lote. Consulte também a opção --protocol para obter uma maneira de fazer com que o rsync criado gere um arquivo em lotes que um rsync mais antigo possa entender. (Observe que os arquivos em lote foram alterados na versão 2.6.3, portanto, misturar versões anteriores a versões novas não funcionará.)

    Ao ler um arquivo em lotes, o rsync forçará o valor de certas opções a corresponderem aos dados no arquivo em lotes, se você não os definir para o mesmo que o comando de gravação em lote. Outras opções podem (e devem) ser alteradas. Por exemplo, as alterações --write-batch para --read-batch, --files-from são descartadas e as opções --filter / - include / - exclude não são necessárias, a menos que uma das opções --delete seja especificada .

    O código que cria o arquivo BATCH.sh transforma qualquer opção de filtro / inclusão / exclusão em uma única lista que é anexada como um documento "aqui" ao arquivo de script do shell. Um usuário avançado pode usar isso para modificar a lista de exclusões, se desejar uma alteração no que é excluído por --delete. Um usuário normal pode ignorar esses detalhes e apenas usar o script de shell como uma maneira fácil de executar o comando --read-batch apropriado para os dados em lote.

    O modo de lote original no rsync foi baseado em "rsync +", mas a versão mais recente usa uma nova implementação.

Eu imagino que você poderia tentar

rsync --write-batch=foo -Pav /junk user@host1:/backup
foo.sh user@host2:/backup
foo.sh user@host3:/backup
Chloe
fonte
O comando sugerido não funciona:remote destination is not allowed with --read-batch
kynan 21/03
Mostre o comando completo. -para um nome de arquivo significa ler da entrada padrão e STDIN também está sendo lido foono exemplo, um arquivo local.
Chloe
2
Essa parece ser a solução maximamente correta para o que eu estava tentando fazer, embora meu caso de uso para isso tenha evaporado há muito tempo no éter. : D
Jessie
4

Você pode tentar usar o uníssono . Deve ser muito mais rápido na criação da lista de arquivos, pois mantém um cache dos arquivos.

Jason Axelson
fonte
2
Nota: O Unison não mantém um 'cache' dos arquivos. Ele mantém apenas um banco de dados com os nomes de arquivos, registros de data e hora e somas de verificação. Ele ainda faz uma varredura do sistema de arquivos e cria uma soma de verificação para comparar com o controle remoto. A única vantagem da Unison é a sincronização bidirecional. Eu recomendo o Unison, mas não vai ajudar aqui.
Chloe
4

O rsync --batch-modesuporta multicast. Se isso for possível na sua rede, pode valer a pena investigar isso.

codecrank
fonte
2

que tal mudar sistemas de arquivos?

Há algum tempo, mudei um FS com vários terabytes do ext3 para o XFS. O tempo para verificar os diretórios (com cerca de 600.000 arquivos da última vez que verifiquei) passou de 15 a 17 minutos para menos de 30 segundos!

Javier
fonte
1

Não é uma resposta direta, mas se você usar o rsync versão 3+, ele começará a ser transferido antes de gerar toda a lista de arquivos.

Outra opção, ainda não muito eficiente, seria executá-los como trabalhos, para que alguns sejam executados ao mesmo tempo.

Além disso, eu pensei nessa estranheza se você não se importa em usar tar:

tar cf - . | tee >(ssh localhost 'cat > test1.tar') >(ssh localhost 'cat > test2.tar') >/dev/null

Onde cada host local seria servidores diferentes, é claro (assume o login baseado em chave). Nunca usei o acima antes, no entanto.

Kyle Brandt
fonte
Hmm! Estranhamente, o cwrsync (rsync 3.0.7) parece não fazer isso. Vou ter que analisar por que isso é assim, pois isso seria uma grande ajuda para reduzir esses enormes tempos de execução. Obrigado!
21710 Jessie
Essa versão dos dois lados?
Kry Brandt
Na verdade não; a máquina local é o cwrsync 3.0.7 e o host remoto (bem, com o qual estou trabalhando agora) é o rsync 3.0.3 no Debian Lenny. Não parece que seria uma diferença de versão muito grande para ele se comportar mal, mas eu não sei .. Vou procurar atualizar o lado do Debian.
21710 Jessie
1
Que estranho versículo. Provavelmente isso funcionaria, se eu não estivesse aproveitando o fato do rsync não precisar reduplicar alguns shows de dados em vários links lentos quando, no máximo, apenas algumas centenas de kb foram alterados. Além disso, obter as duas extremidades no (cw) rsync 3.0.7 ainda fazia a construção da lista de arquivos e a transferência em série. Não estou muito preocupado com isso, no entanto.
Jessie
Não é "tar cf -." o mesmo que "tar c". ?
Johan Boulé
1

Que tal executar os trabalhos rsync do host1, host2 e host3? Ou, execute um trabalho para copiar para o host1 e execute-o no host2 e host3 para obtê-lo do host1.

mfinni
fonte
1

Uma solução melhor seria criar um repositório com o git e enviar para os 3 hosts. Mais rápido, você não precisaria da parte da lista de arquivos e ela consome menos recursos.

Boa sorte,
João Miguel Neves

jneves
fonte
10
O git não preserva os tempos de modificação nem as permissões (exceto o bit de execução) e exigiria o armazenamento de uma segunda cópia dos dados como objetos git, .git/embora os envios para os controles remotos que já teriam a maioria dos dados fossem mais rápidos. O git não substitui o rsync.
Dan D.
Além disso, o git pode ser visualizado publicamente, a menos que você pague.
Chloe
8
@Chloe, você confunde o git com o GitHub. O próprio Git é um sistema de controle de versão distribuído de código aberto e qualquer pessoa pode hospedar o repositório git por qualquer meio, incluindo http, nfse afp. O GitHub é um site que cuida da criação e manutenção de repositórios git para você e os torna públicos (a menos que você pague).
toriningen
1
O @Chloe GitHub pode ser visualizado publicamente, mas o BitBucket fornece repositórios privados.
SWS
2
Além disso, o Git não controla diretórios vazios.
Flimm
1

Ao procurar essa resposta, acho que você precisaria fazer um lote usando o rsync primeiro e depois enviá-lo a todos, o que tornaria a lista de arquivos triturada apenas uma vez e então você poderia apenas fundo todos os três rsyncs para executá-los em paralelo.

Morgan
fonte
1

Outra solução possível é apenas executar tantos processos rsync em paralelo quanto os hosts, ou seja, fork.

Alexey Tigarev
fonte