Rsync in parallelo


30

Mi sono appena spostato e ho scoperto dopo qualche prova ed errore che da qualche parte tra la mia casa e il mio server remoto, c'è qualche limitazione in corso ... ma la limitazione non è molto intelligente. Limita solo le connessioni individuali. Quindi, se copio un file da 1 GB, procederà allegramente a 150 kBps. Ma se inizializzo 10 copie, ognuna di esse andrà a 150 kBps (ovvero ottengo una larghezza di banda aggregata molto più elevata su più connessioni).

Uso rsync abbastanza spesso per sincronizzare alcuni grandi set di dati dal lavoro a casa (fortunatamente sotto forma di molti file). C'è un modo per dire a rsync di scaricare usando più connessioni? Teoricamente dovrebbe essere possibile dal momento che, per quanto posso dire, rsync fa prima un passaggio per determinare le modifiche necessarie e quindi esegue la trasmissione effettiva. Punti bonus se c'è un modo magico di dire a rsync di dividere i singoli file in N pezzi e poi ricomporli. Credo che CuteFTP sia effettivamente abbastanza intelligente da riuscirci.

Risposte:


13

Ho avuto un problema simile dovendo spostare diversi TB da un NAS a un altro NAS senza capacità di backup / ripristino che mi permettesse di alimentare solo 1 set all'altro.

Quindi ho scritto questo script per eseguire 1 rsync per ogni directory che incontra. Dipende dal fatto di essere in grado di elencare le directory di origine (fare attenzione a sfuggire a ARG 3) ma penso che potresti impostare quel palcoscenico con una rsync non ricorsiva che ha appena copiato i file e le directory al livello appropriato.

Determina anche quanti rsync devono essere eseguiti in base al numero di processori, ma potresti volerlo modificare.

L'altra possibile opzione che viene in mente è: eseguire un rsync in modalità --list-only.

Questo ti darebbe tutti i file che devono essere aggiornati. Quindi esegui 1 rsync per ogni file nella tua lista se hai usato xargs per gestire il numero di rsync che hai fatto, questo potrebbe essere molto elegante. In realtà probabilmente una soluzione più elegante della mia piccola sceneggiatura qui ...

#! /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
Funziona - puoi apportare molti miglioramenti al suo funzionamento, ma il concetto di usare xargs per parallelizzare la tua applicazione è piuttosto nuovo.
MattPark,

6

GNU Parallel ha una soluzione

Ho spostato 15 TB a 1 Gbps e può saturare il collegamento a 1 Gbps.

Di seguito verrà avviato un rsync per file di grandi dimensioni in src-dir in dest-dir sul server fooserver:

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

Le directory create potrebbero finire con autorizzazioni errate e i file più piccoli non vengono trasferiti. Per correggere quelli eseguono rsync un'ultima volta:

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

1
Ti dispiacerebbe incollare la sezione "ESEMPIO: Parallelizzare rsync" nella tua risposta. Nel caso in cui il collegamento si interrompa in futuro.
picobit,

3

Sì. Tale caratteristica esiste.

C'è un'utilità chiamata pssh che fornisce la funzionalità descritta.

Questo pacchetto fornisce versioni parallele degli strumenti openssh. Incluso nella distribuzione:

  • Parallel ssh (pssh)
  • Parallel scp (pscp)
  • Rsync parallelo (prsync)
  • Nuke parallelo (pnuke)
  • Slurp parallelo (pslurp)

Non sono sicuro di quanto sia facile da configurare, ma potrebbe fare il trucco!


26
Le utility pssh vengono utilizzate per diffondere i comandi su più server, non eseguire lo stesso comando più volte su un server. In particolare, prsync supporta solo l'invio di un file sul computer locale a più macchine esterne. Non supporta il download di un file remoto con più connessioni.
Derek Dahmer,

1
Dato il commento di DerekDahmer, il poster di questa risposta potrebbe volerlo ritirare?
MC0e

3

Non posso commentare, quindi ho aggiunto una nuova risposta, con un codice leggermente migliore rispetto al precedente (bello e intelligente).

Controlla la rsynclinea, perché contiene un ionicetweak opzionale .

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

Sembra che qualcuno abbia scritto questa utility per te. Rompe il trasferimento in blocchi paralleli. Questa è un'implementazione migliore rispetto alla versione "file parallelo grande" elencata sotto GNU Parallel:

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

Inoltre, lftp può parallelizzare i trasferimenti di file tramite ftp, ftps, http, https, hftp, fish, sftp. Molte volte, ci sono alcuni vantaggi nell'uso di lftp, perché la gestione dei permessi, l'accesso limitato, ecc. Per rsync può essere impegnativo.


Mentre funziona, può causare una notevole quantità di frammentazione del disco rapidamente, poiché non stai semplicemente usando più connessioni per scaricare lo stesso file.
bparker

1

No. Non esiste una tale funzione. È possibile dividere la sincronizzazione in più chiamate, rsyncse proprio lo si desidera.

Ti suggerirei di trovare qualunque cosa stia facendo questo limite di velocità e di parlare seriamente con chiunque lo mantenga / lo gestisca.


4
Spesso tali restrizioni provengono da alcuni ISP come Comcast. Buona fortuna con qualsiasi tipo di conversazione ragionevole con loro.
James Moore,

1

Volevo trasferire diverse directory (con molti file) contemporaneamente, quindi ho creato questo piccolo 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."

Ho fatto questo script abbastanza velocemente, quindi per favore rivedilo e testalo prima di usarlo in un ambiente di produzione.


0

Ho creato il seguente script per caricare molte cartelle con immagini in parallelo. Lo esegui prima con la destinazione di sincronizzazione e poi con tutti i nomi delle cartelle da copiare.

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

Fa precedere il nome della cartella in giallo su tutto l'output della console rsync per renderlo carino.


-1

Aria2 è un buon programma client per scaricare dati usando molte connessioni da molti mirror. Non supporta SFTP. Quindi, ho installato il server FTP - vsftpd . La mia connessione 3G funziona a piena potenza con 5 connessioni al server FTP.


1
Ti andrebbe di approfondire questo per rendere utile la tua risposta?
Tog
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.