Rsync en paralelo


30

Me acabo de mudar y descubrí, después de una prueba y error, que en algún lugar entre mi hogar y mi servidor remoto, hay una aceleración ... pero la aceleración no es muy inteligente. Solo acelera las conexiones individuales. Entonces, si copio un archivo de 1 GB, procederá alegremente a 150 kBps. Pero si inicializo 10 copias, cada una de ellas irá a 150 kBps (es decir, obtendré un ancho de banda agregado mucho mayor en varias conexiones).

Utilizo rsync con bastante frecuencia para sincronizar algunos conjuntos de datos grandes del trabajo al hogar (afortunadamente en forma de muchos archivos). ¿Hay alguna manera de decirle a rsync que descargue usando múltiples conexiones? Teóricamente debería ser posible ya que, por lo que puedo decir, rsync primero hace un pase para determinar los cambios necesarios y luego realiza la transmisión real. Puntos de bonificación si hay una manera mágica de decirle a rsync que corte los archivos individuales en N piezas y luego los vuelva a unir. Creo que CuteFTP es lo suficientemente inteligente como para lograrlo.

Respuestas:


13

Acabo de tener un problema similar al tener que mover varios TB de un NAS a un NAS diferente sin capacidad de copia de seguridad / restauración que me permitiría alimentar 1 juego al otro.

Entonces escribí este script para ejecutar 1 rsync para cada directorio que encuentra. Depende de poder enumerar los directorios de origen (tenga cuidado de escapar de ARG 3), pero creo que podría establecer esa etapa con un rsync no recursivo que solo copiaba archivos y directorios al nivel apropiado.

También determina cuántos rsync se ejecutarán en función de la cantidad de procesadores, pero es posible que desee ajustar eso.

La otra opción posible que viene a la mente es: ejecutar un rsync en modo --list-only.

Eso le daría todos los archivos que necesitan actualizarse. Luego ejecute 1 rsync para cada archivo en su lista si usó xargs para administrar la cantidad de rsyncs que tenía, esto podría ser muy elegante. En realidad, probablemente sea una solución más elegante que mi pequeño script aquí ...

#! /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
Esto funciona: puede hacer muchas mejoras en su funcionamiento, pero el concepto de usar xargs para paralelizar su aplicación es bastante novedoso.
MattPark

6

GNU Parallel tiene una solución

He movido 15 TB a 1 Gbps y puede saturar el enlace de 1 Gbps.

Lo siguiente iniciará un rsync por archivo grande en src-dir a dest-dir en el servidor de búsqueda:

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

Los directorios creados pueden terminar con permisos incorrectos y no se transfieren archivos más pequeños. Para arreglar esos ejecute rsync por última vez:

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

1
¿Le importaría pegar la sección "EJEMPLO: Paralelizar rsync" en su respuesta. Por si acaso el enlace se rompe en el futuro.
picobit

3

Sí. Tal característica existe.

Hay una utilidad llamada pssh que proporciona la funcionalidad descrita.

Este paquete proporciona versiones paralelas de las herramientas openssh. Incluido en la distribución:

  • Ssh paralelo (pssh)
  • SCP paralelo (pscp)
  • Rsync paralelo (prsync)
  • Nuke paralelo (pnuke)
  • Sorbo paralelo (pslurp)

No estoy seguro de lo fácil que es configurarlo, ¡pero podría ser suficiente!


26
Las utilidades pssh se utilizan para distribuir comandos en varios servidores, no para ejecutar el mismo comando varias veces en un servidor. En particular, prsync solo admite el envío de un archivo en su máquina local a múltiples máquinas externas. No es compatible con la descarga de un archivo remoto con múltiples conexiones.
Derek Dahmer

1
Dado el comentario de @ DerekDahmer, ¿el póster de esta respuesta podría querer retirarlo?
mc0e

3

No puedo comentar, así que he agregado una nueva respuesta, con un código un poco mejor que el código anterior (bonito e inteligente).

Verifique la rsynclínea, porque contiene un 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 alguien ha escrito esta utilidad para ti. Rompe la transferencia en trozos paralelos. Esta es una mejor implementación que la versión de "archivo grande paralelo" que se enumera en GNU Parallel:

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

Además, lftp puede paralelizar transferencias de archivos a través de ftp, ftps, http, https, hftp, fish, sftp. Muchas veces, el uso de lftp tiene algunas ventajas, porque administrar permisos, acceso restringido, etc. para rsync puede ser un desafío.


Si bien esto funciona, puede causar una gran cantidad de fragmentación del disco rápidamente, ya que no está simplemente usando múltiples conexiones para descargar el mismo archivo.
bparker

1

No. No existe tal característica. Puede dividir la sincronización en varias llamadas rsyncsi realmente lo desea.

Te sugiero que encuentres lo que sea que esté haciendo esta limitación de velocidad y que hables seriamente con quien lo mantenga / administre.


44
Con frecuencia, esas restricciones son de algunos ISP como Comcast. Buena suerte teniendo cualquier tipo de conversación razonable con ellos.
James Moore

1

Quería transferir varios directorios (con muchos archivos) al mismo tiempo, así que creé este pequeño 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."

Hice este script bastante rápido, así que revíselo y pruébelo antes de usarlo en un entorno de producción.


0

Creé el siguiente script para cargar muchas carpetas con imágenes en paralelo. Lo ejecutas primero con el objetivo de sincronización y luego con todos los nombres de carpetas 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

Prefija el nombre de la carpeta en amarillo a toda la salida de la consola rsync para que se vea bonita.


-1

Aria2 es un buen programa cliente para descargar datos utilizando muchas conexiones desde muchos espejos. No es compatible con SFTP. Entonces, instalé el servidor FTP - vsftpd . Mi conexión 3g funciona a plena potencia con 5 conexiones al servidor FTP.


1
¿Te gustaría ampliar eso para que tu respuesta sea útil?
Tog
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.