Paralelização do rsync

30

Acabei de me mudar e descobri que após uma tentativa e erro em algum lugar entre minha casa e meu servidor remoto, há algum afogamento acontecendo ... mas o afogamento não é muito inteligente. Ele apenas limita as conexões individuais. Então, se eu copiar um arquivo de 1 GB, ele prosseguirá alegremente a 150 kBps. Mas se eu inicializar 10 cópias, cada uma delas terá 150 kBps (ou seja, eu obtenho uma largura de banda agregada muito maior em várias conexões).

Eu 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 dizer ao rsync para baixar usando várias conexões? Teoricamente, isso deve ser possível, já que, até onde eu sei, o rsync primeiro faz um passe para determinar as mudanças necessárias e então realiza a transmissão real. Pontos de bônus, se houver uma maneira mágica de dizer ao rsync para fatiar arquivos individuais em N pedaços e depois juntá-los novamente. Acredito que CuteFTP é realmente inteligente o suficiente para conseguir isso.

    
por stuyguy 03.11.2011 / 00:47

9 respostas

13

Acabei de ter um problema semelhante ao mover vários TB de um NAS para um NAS diferente sem recurso de backup / restauração, o que permitiria que eu apenas alimentasse um conjunto para o outro.

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

Ele também determina quantos rsyncs serão executados com base no número de processadores, mas você pode querer ajustar isso.

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

Isso forneceria todos os arquivos que precisam ser atualizados Em seguida, execute 1 rsync para cada arquivo em sua lista, se você usou xargs para gerenciar o número de rsyncs que você tinha, isso poderia ser muito elegante. Na verdade, provavelmente uma solução mais elegante do que o meu pequeno roteiro 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}/%/
    
por 16.12.2011 / 01:03
7

O GNU Parallel tem uma solução .

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

O seguinte irá iniciar um rsync por arquivo grande em src-dir para dest-dir no servidor do servidor:

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

Os dirs criados podem acabar com permissões erradas e arquivos menores não estão sendo transferidos. Para corrigir esses rsync executar uma última vez:

rsync -Havessh src-dir/ fooserver:/dest-dir/
    
por 26.01.2013 / 12:52
3

Sim. Tal recurso existe.

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

This package provides parallel versions of the openssh tools. Included in the distribution:

  • Parallel ssh (pssh)
  • Parallel scp (pscp)
  • Parallel rsync (prsync)
  • Parallel nuke (pnuke)
  • Parallel slurp (pslurp)

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

    
por 03.11.2011 / 01:48
3

Não posso comentar, por isso adicionei uma nova resposta, com um código um pouco melhor do que a anterior (interessante & smart) código.

Verifique a linha rsync , porque ela contém um ajuste ionice 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
[email protected]:/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
    
por 23.02.2016 / 21:51
2

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

link

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

    
por 30.10.2013 / 17:45
1

Não. Nenhum recurso desse tipo existe. Você poderia dividir a sincronização em várias chamadas para rsync , se realmente quisesse.

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

    
por 03.11.2011 / 00:59
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
[email protected]:/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 rapidamente, por isso revise-o e teste-o antes de usá-lo em um ambiente de produção.

    
por 12.09.2014 / 07:23
0

Eu criei o script a seguir para fazer o upload de muitas pastas com imagens em paralelo. Você o executa primeiro com o alvo de sincronização e depois com todos os nomes das pastas para copiar.

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

Prefixa o nome da pasta em amarelo para todas as saídas do console rsync para torná-lo bonito.

    
por 15.05.2016 / 19:30
-1

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

    
por 03.09.2013 / 21:43