Featured image of post Rsync y Parallel, copias de archivos realmente intensas

Rsync y Parallel, copias de archivos realmente intensas

Un interesante script para hacer copias concurrentes usando rsync y GNU Parallel que pondrán a prueba la capacidad de tu computadora.

El otro día pasó a mejor vida un disco duro externo en el que generalmente hago mis respaldos automáticos. Mientras que consigo otro decidí hacer las copias en una carpeta privada en la computadora que funciona como NAS .

La cantidad de datos es importante, estoy hablando de unos cientos de gigabytes y la primer copia puede durar varias horas.

Rsync y Parallel

Buscando en internet me topé con este script llamado rsync_parallel que me resultó muy interesante.

#!/bin/bash
set -e

# Uso:
#   rsp.sh [--parallel=N] [opciones de rsync]
#
# Options:
#   --parallel=N         Utiliza N procesos paralelos para transferir los archivos.
#                    El valor por defualt es de 10.
#
# Notas:
#   * Requiere GNU Parallel
#   * Utilizar este script con ssh-keys = Un montón de solicitudes de contraseña.
#   * Primero hace una lista de los archivos que han cambiado, luego parte esta
#     lista en N pedazos y le encarga a rsync la copia de cada uno de esos pedazos.
#   * Hay que tener cuidado con las con las opciones que pasan a través de rsync.
#     las normales va a funcionar, es posible que desee probar opciones extrañas
#     por adelantado.
#
#   Gracias a rcoup por este script https://gist.github.com/rcoup/5358786
#

if [[ "$1" == --parallel=* ]]; then
        PARALLEL="${1##*=}"
        shift
else
        PARALLEL=10
fi
echo "Utilizando $PARALLEL procesos para la transferencia de archivos..."

TMPDIR=$(mktemp -d)
trap "rm -rf $TMPDIR" EXIT

echo "Calculando la lista de archivos..."
# sorted by size (descending)
rsync $@ --out-format="%l %n" --no-v --dry-run | sort -n -r > $TMPDIR/files.all

# check for nothing-to-do
TOTAL_FILES=$(cat $TMPDIR/files.all | wc -l)
if [ "$TOTAL_FILES" -eq "0" ]; then
        echo "Nada que transferir :)"
        exit 0
fi

function array_min {
        # return the (index, value) of the minimum element in the array
        IC=($(tr ' ' '\n' <<<$@ | cat -n | sort -k2,2nr | tail -n1))
        echo $((${IC[0]} - 1)) ${IC[1]}
}

echo "Generando los pedazos..."
# declare chunk-size array
for ((I = 0 ; I < PARALLEL ; I++ )); do
        CHUNKS["$I"]=0
done

# add each file to the emptiest chunk, so they're as balanced by size as possible
while read FSIZE FPATH; do
        MIN=($(array_min ${CHUNKS[@]}))
        CHUNKS["${MIN[0]}"]=$((${CHUNKS["${MIN[0]}"]} + $FSIZE))
        echo $FPATH >> $TMPDIR/chunk.${MIN[0]}
done < $TMPDIR/files.all

find "$TMPDIR" -type f -name "chunk.*" -printf "\n*** %p ***\n" -exec cat {} \;

echo "Iniciando la transferencia de archivos..."
find "$TMPDIR" -type f -name "chunk.*" | parallel -j $PARALLEL -t --verbose --progress rsync --files-from={} $@

Divide y vencerás

Tiene un enfoque muy interesante, primero obtiene una lista completa de los archivos que se van a copiar y luego divide esa lista en varios archivos de una forma equilibrada.

El total de archivos corresponde al número de procesos concurrentes que queremos trabajar, por default es 10 pero se puede cambiar con un parámetro.

Una vez que tenemos nuestras listas el programa parallel inicia la copia de los archivos con rsync y le entrega una lista de los archivos a cada proceso que se ejecuta simultaneamente.

El problema es el ancho de banda.

Gráfica del tráfico por hora

Gráfica del tráfico por hora

El problema es que ahora tengo 10 procesos peleándose el ancho de banda, que lamentablemente es poco en mi caso. Supongo que una copia con una buena velocidad o de un disco duro a otro la copia de archivos volaría.

También pueden notar que el equipo se puede comportar un poco lento, eso depende de los recursos de su computadora. Eso se debe al uso intensivo del disco duro durante la copia de los archivos.

El uso de parallel es interesante, actualmente estoy jugando con el número de procesos a ejecutar. Si utilizo pocos, más o menos sería lo mismo que ejecutar un rsync simple. Si uso muchos, los pedazos serán más pequeños, pero el uso del disco será mayor.

copiando ando \| rsync parallel

copiando ando | rsync parallel

Les paso el dato por si algún día se les ofrece hacer una copia masiva de archivos.

Enlaces

Licensed under CC BY-NC-SA 4.0
Última actualización 20 feb. 2014 220:00 CST
Todas las imágenes, nombres de productos y nombres de empresa o logotipos citados en esta página web son propiedad de sus respectivos propietarios.
Creado con Hugo
Tema Stack diseñado por Jimmy