Paralelizando o rsync


30

Acabei de me mudar e descobri, após algumas tentativas e erros, que em algum lugar entre minha casa e meu servidor remoto, há alguma aceleração acontecendo ... mas a aceleração não é muito inteligente. Ele apenas limita as conexões individuais. Portanto, se eu copiar um arquivo de 1 GB, ele prosseguirá alegremente a 150 kBps. Porém, se eu inicializar 10 cópias, cada uma delas atingirá 150 kBps (ou seja, obterá uma largura de banda agregada muito maior em várias conexões).

Uso o rsync com bastante frequência para sincronizar alguns grandes conjuntos de dados do trabalho para casa (felizmente na forma de muitos arquivos). Existe uma maneira de solicitar ao rsync que faça o download usando várias conexões? Teoricamente, isso deve ser possível, pois, até onde eu sei, o rsync primeiro faz um passo para determinar as alterações necessárias e depois executa a transmissão real. Pontos de bônus se houver uma maneira mágica de dizer ao rsync para dividir arquivos individuais em N pedaços e depois juntá-los novamente. Acredito que o CuteFTP é realmente inteligente o suficiente para fazer isso.

Respostas:


13

Eu apenas tive um problema semelhante ao transferir vários TB de um NAS para outro NAS sem capacidade de backup / restauração que me permitisse alimentar apenas 1 conjunto para o outro.

Então, eu escrevi esse script para executar 1 rsync para cada diretório que encontrar. Depende da capacidade de listar os diretórios de origem (tenha cuidado para escapar do ARG 3), mas acho que você pode definir esse estágio com um rsync não recursivo que apenas copiou arquivos e diretórios para o nível apropriado.

Ele também determina quantos rsync serão executados com base no número de processadores, mas você pode querer ajustá-lo.

A outra opção possível que vem à mente é: execute um rsync no modo --list-only.

Isso daria a você todos os arquivos que precisam ser atualizados. Em seguida, execute 1 rsync para cada arquivo em sua lista, se você usasse o xargs para gerenciar o número de rsyncs disponíveis, isso seria muito elegante. Na verdade, provavelmente uma solução mais elegante do que meu pequeno script aqui ...

#! /bin/bash
SRC_DIR=$1
DEST_DIR=$2
LIST=$3
CPU_CNT=`cat /proc/cpuinfo|grep processor |wc -l`
#  pseudo random heuristic
let JOB_CNT=CPU_CNT*4
[ -z "$LIST" ] && LIST="-tPavW --exclude .snapshot --exclude hourly.?"
echo "rsyncing From=$SRC_DIR To=$DEST_DIR DIR_LIST=$LIST"
mkdir -p /{OLD,NEW}_NAS/home
[ -z "$RSYNC_OPTS" ] && RSYNC_OPTS="-tPavW --delete-during --exclude .snapshot --exclude hourly.?"
cd $SRC_DIR
echo $LIST|xargs -n1 echo|xargs -n1 -P $JOB_CNT -I% rsync ${RSYNC_OPTS} ${SRC_DIR}/%/ ${DEST_DIR}/%/

2
Isso funciona - você pode fazer muitas melhorias em como ele funciona, mas o conceito de usar xargs para paralelizar seu aplicativo é bastante novo.
MattPark

6

O GNU Parallel tem uma solução

Mudei 15 TB por 1 Gbps e ele pode saturar o link de 1 Gbps.

A seguir, será iniciado um rsync por arquivo grande no src-dir para dest-dir no servidor fooserver:

cd src-dir; find . -type f -size +100000 | \
parallel -v ssh fooserver mkdir -p /dest-dir/{//}\; \
  rsync -s -Havessh {} fooserver:/dest-dir/{}

Os diretórios criados podem ter permissões incorretas e arquivos menores não estão sendo transferidos. Para corrigir aqueles que executam o rsync uma última vez:

rsync -Havessh src-dir/ fooserver:/dest-dir/

1
Você se importaria de colar a seção "EXEMPLO: Paralelizando o rsync" em sua resposta. Apenas no caso de o link quebrar no futuro.
Picobit 15/05

3

Sim. Esse recurso existe.

Existe um utilitário chamado pssh que fornece a funcionalidade descrita.

Este pacote fornece versões paralelas das ferramentas openssh. Incluído na distribuição:

  • Paralelo ssh (pssh)
  • Scp paralelo (pscp)
  • Rsync paralelo (prsync)
  • Nuke paralelo (pnuke)
  • Slurp paralelo (pslurp)

Não sei ao certo como é fácil configurar, mas isso pode ser suficiente!


26
Os utilitários pssh são usados ​​para espalhar comandos por vários servidores, não executam o mesmo comando várias vezes em um servidor. Em particular, o prsync suporta apenas o envio de um arquivo em sua máquina local para várias máquinas externas. Ele não suporta o download de um arquivo remoto com várias conexões.
Derek Dahmer

1
Dado o comentário de @ DerekDahmer, o autor desta resposta pode querer retirá-la?
Mc0e 06/0318

3

Não posso comentar, por isso adicionei uma nova resposta, com um código um pouco melhor que o código anterior (agradável e inteligente).

Verifique a rsynclinha, pois ela contém um ioniceajuste opcional .

#!/bin/bash
start_time=$(date +%s.%N)
# Transfer files in parallel using rsync (simple script)
# MAXCONN: maximum number "rsync" processes running at the same time:
MAXCONN=6
# Source and destination base paths. (not need to end with "/")
SRC_BASE=/home/user/public_html/images
DST_BASE=user@hostname.domain.local:/home/user/public_html/images
RSYNC_OPTS="-ah --partial"
# Main loop:
for FULLDIR in $SRC_BASE/*; do
    NUMRSYNC=`ps -Ao comm | grep '^'rsync'$' | wc -l `
    while [ $NUMRSYNC -ge $MAXCONN ]; do
        NUMRSYNC=`ps -Ao comm | grep '^'rsync'$' | wc -l `
        sleep 1
    done
    DIR=`basename $FULLDIR`
    echo "Start: " $DIR
    ionice -c2 -n5 rsync $RSYNC_OPTS $SRC_BASE/${DIR}/ $DST_BASE/${DIR}/ &
    # rsync $RSYNC_OPTS $SRC_BASE/${DIR}/ $DST_BASE/${DIR}/ &
    sleep 5
done

execution_time=$(echo "$(date +%s.%N) - $start" | bc)
printf "Done. Execution time: %.6f seconds\n" $execution_time

2

Parece que alguém escreveu este utilitário para você. Ele divide a transferência em pedaços paralelos. Esta é uma implementação melhor do que a versão "paralelamente arquivo grande" listada em GNU Parallel:

https://gist.github.com/rcoup/5358786

Além disso, o lftp pode paralelizar transferências de arquivos via ftp, ftps, http, https, hftp, fish, sftp. Muitas vezes, existem algumas vantagens em usar o lftp, porque gerenciar permissões, acesso restrito etc. para o rsync pode ser um desafio.


Enquanto isso funciona, pode causar uma enorme quantidade de fragmentação de disco rapidamente, pois você não está simplesmente usando várias conexões para baixar o mesmo arquivo.
bparker

1

Não. Não existe esse recurso. Você pode dividir a sincronização em várias chamadas, rsyncse realmente quiser.

Eu sugiro que você encontre o que está fazendo esse limite de taxa e tenha uma conversa séria com quem o mantém / gerencia.


4
Freqüentemente essas restrições são de alguns provedores como a Comcast. Boa sorte em ter qualquer tipo de conversa razoável com eles.
James Moore

1

Eu queria transferir vários diretórios (com muitos arquivos) ao mesmo tempo, então criei este pequeno script:

#!/bin/bash
# Transfer files in parallel using rsync (simple script)
# MAXCONN: maximum number "rsync" processes running at the same time:
MAXCONN=10
# Source and destination base paths. (not need to end with "/")
SRC_BASE=/home/sites
DST_BASE=user@example.com:/var/www
RSYNC_OPTS="--stats -ilrtpog"
# Main loop:
for FULLDIR in $SRC_BASE/*/; do
    NUMRSYNC=`ps -Ao comm | grep '^'rsync'$' | wc -l `
    while [ $NUMRSYNC -ge $MAXCONN ]; do
        NUMRSYNC=`ps -Ao comm | grep '^'rsync'$' | wc -l `
        sleep 10
    done
    DIR=`basename $FULLDIR`
    rsync $RSYNC_OPTS $SRC_BASE/${DIR}/ $DST_BASE/${DIR}/ & 
    sleep 1 
done
echo "Done."

Eu fiz esse script muito rápido, portanto, revise-o e teste-o antes de usá- lo em um ambiente de produção.


0

Criei o seguinte script para fazer upload de muitas pastas com imagens em paralelo. Você o executa primeiro com o destino de sincronização e depois com todos os nomes de pastas a serem copiados.

#!/bin/sh

dest="$1"
shift

if [ "$dest" = "" ]; then
    echo "USAGE: $0 TARGET:/foo/bar <dir1> [dir2] [dir3]"
    exit 1
fi

RCol='\x1B[0m' # Text Reset
BYel='\x1B[1;33m';

for i in "$@"; do
    prefix=`printf "$BYel%50s:$RCol" "$i"`
    echo "$prefix * Starting $i"
    echo "$prefix -> syncing '$i/' to '$dest/$i/'"
    (rsync -rv "$i/" "$dest/$i/") 2>&1 | sed "s/^/$prefix /g" &
    sleep 0.5
done

echo "* Waiting for all to complete"
wait

Ele prefixa o nome da pasta em amarelo para todas as saídas do console rsync para torná-la bonita.


-1

O Aria2 é um bom programa cliente para baixar dados usando muitas conexões de vários espelhos. Não suporta SFTP. Então, eu instalei o servidor FTP - vsftpd . Minha conexão 3G funciona com potência máxima com 5 conexões com o servidor FTP.


1
Você gostaria de expandir isso para tornar sua resposta útil?
Tog
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.