Copia de archivos con multihilo rápido parsyncfp
Introducción
parsyncfp es un wrapper paralelo de rsync que acelera la transferencia de grandes colecciones de archivos ejecutando varios procesos rsync a la vez. Cada proceso sincroniza su propio bloque de archivos, por lo que el ancho de banda y la CPU disponibles se utilizan de forma más eficiente que con un único flujo de rsync.
Esta guía explica cuándo parsyncfp resulta útil, cómo instalarlo y cómo ejecutar una transferencia básica entre dos servidores.
La copia paralela acelera las transferencias sólo en discos rápidos y una red estable. En discos lentos o sistemas de archivos montados por red (NFS, SMB, FUSE), aumentar el número de procesos paralelos a menudo no proporciona ninguna ganancia de velocidad y puede, en cambio, generar carga adicional en el origen, el destino o el enlace entre ellos. Comience con un número pequeño de procesos, mida el resultado y aumente el número sólo si los discos y la red pueden mantener el ritmo.
Cómo funciona parsyncfp
parsyncfp utiliza la utilidad fpart para dividir el árbol de archivos de origen en bloques de tamaño aproximadamente igual, y luego lanza varios procesos rsync en paralelo, uno por bloque. Como fpart divide el árbol de forma incremental, parsyncfp puede empezar a transferir archivos antes de que se complete el escaneo completo del árbol de origen, lo que importa para árboles de directorios muy grandes.
La herramienta sólo necesita instalarse en el servidor de origen. rsync gestiona el lado receptor como de costumbre.
El mismo autor mantiene un sucesor llamado parsyncfp2 (pfp2), que incluye correcciones de errores y mejoras respecto a parsyncfp y además admite el envío desde varios hosts de origen a la vez. Para nuevos despliegues, parsyncfp2 es la opción recomendada. Esta guía cubre el parsyncfp clásico; la sintaxis de los comandos de pfp2 es en gran medida compatible.
Cuándo es útil parsyncfp
parsyncfp aporta el mayor beneficio cuando:
- el origen contiene millones de archivos pequeños, en los que rsync pasa la mayor parte de su tiempo en operaciones de metadatos en lugar de transferencia de datos real;
- tanto el origen como el destino están respaldados por almacenamiento rápido (NVMe, SSD o un RAID bien ajustado);
- la red entre el origen y el destino es rápida y estable (1 Gbps o más, baja pérdida de paquetes);
- un único proceso rsync está limitado por la CPU o por el rendimiento por flujo, no por el disco o el enlace.
Para directorios pequeños, discos giratorios lentos o una red saturada, suele ser suficiente con rsync simple.
El directorio ~/.parsyncfp
parsyncfp crea un directorio de caché llamado ~/.parsyncfp en el servidor de origen. Dentro encontrará el subdirectorio fpcache, que contiene el log de fpart, los archivos PID de los procesos rsync en ejecución y los archivos de chunk que listan qué rutas debe copiar cada rsync. Los archivos de registro están fechados y no se sobrescriben entre ejecuciones, por lo que se pueden revisar más tarde.
Si desea ejecutar varias instancias de parsyncfp al mismo tiempo, indique a cada una una ubicación de caché separada con la opción --altcache. parsyncfp detecta otras instancias en ejecución al inicio y advierte sobre ellas, por lo que las ejecuciones superpuestas accidentales se hacen visibles pronto.
Instalación de las dependencias
parsyncfp en sí depende de rsync (el transporte) y fpart (para dividir el árbol de origen en bloques). Instale ambos en el servidor de origen.
En Debian y Ubuntu:
apt-get install rsync fpart
En RHEL, CentOS Stream, AlmaLinux y Rocky Linux, fpart no está en los repositorios base. Habilite primero el repositorio EPEL y luego instale ambos paquetes:
dnf install epel-release dnf install rsync fpart
Algunos paquetes de EPEL dependen de paquetes del repositorio PowerTools o CRB, que está deshabilitado por defecto. Habilite el correcto para su versión:
# RHEL/AlmaLinux/Rocky Linux 9 y posteriores dnf config-manager --set-enabled crb # RHEL/AlmaLinux/Rocky Linux 8 dnf config-manager --set-enabled powertools
Si su distribución no incluye fpart en absoluto (por ejemplo, RHEL 10 o sus reconstrucciones en el momento de escribir esto), o prefiere no usar EPEL, compile fpart desde el código fuente. El repositorio oficial es el repositorio fpart en GitHub; el README enumera un pequeño conjunto de dependencias de compilación (un compilador de C, make y las cabeceras estándar de la biblioteca C).
Instalación de parsyncfp
parsyncfp es un único script Perl alojado en GitHub. Descárguelo, hágalo ejecutable y muévalo a un directorio en su PATH para poder llamarlo sin escribir la ruta completa:
wget https://raw.githubusercontent.com/hjmangalam/parsyncfp/master/parsyncfp chmod +x parsyncfp sudo mv parsyncfp /usr/local/bin/
Verifique que el script se ejecuta:
parsyncfp --help
Si aparece la pantalla de ayuda, parsyncfp está listo para usarse.
Configuración del acceso SSH al destino
parsyncfp ejecuta rsync sobre SSH, por lo que el servidor de origen debe poder iniciar sesión en el destino sin contraseña. Genere un par de claves en el origen (si aún no existe) y copie la clave pública al destino:
ssh-keygen ssh-copy-id user@target_host
Reemplace user@target_host con el nombre de usuario y la IP o el nombre de host de su servidor de destino. Después de este paso, el siguiente comando debería conectarse sin solicitar contraseña:
ssh user@target_host
Ejecución de una transferencia
Un comando parsyncfp típico tiene este aspecto:
parsyncfp --NP=8 --altcache=/dir/local/tmp --startdir=/dir/local/ www/ [email protected]:/var/dir/
Este comando inicia 8 procesos rsync, usa /dir/local/tmp como directorio de caché y copia el contenido de /dir/local/www en /var/dir/ del host de destino 192.168.67.1.
Preste atención a la barra final en el argumento de origen: www/ copia el contenido del directorio www al destino (como en el ejemplo anterior), mientras que www (sin barra) copia el propio directorio www, creando /var/dir/www/ en el destino. Este es el mismo comportamiento que el rsync simple.
Parámetros principales del comando
- --NP establece el número de procesos rsync paralelos. Un punto de partida razonable es de 4 a 8; aumente el número gradualmente, y sólo si los discos y la red aún no están saturados. Establecer --NP igual al número de núcleos de CPU rara vez es la opción correcta por sí sola.
- --altcache especifica un directorio de caché alternativo. Es útil cuando se ejecutan varias instancias de parsyncfp a la vez o cuando la ubicación predeterminada está en almacenamiento lento. Evite apuntar a una ubicación respaldada por tmpfs (como /tmp en muchas distribuciones), ya que las listas de chunks para árboles de origen muy grandes pueden crecer y no querrá que consuman la RAM.
- --startdir establece el directorio de trabajo utilizado como base para las rutas de origen que le siguen.
Los argumentos después de --startdir son los directorios de origen a copiar (uno o varios, separados por espacios), seguidos del destino al estilo rsync en la forma user@host:/path/.
Para la lista completa de opciones, ejecute parsyncfp --help o consulte la documentación upstream.
Opciones adicionales útiles
Una vez que funcione la transferencia básica, vale la pena conocer algunas opciones para ejecuciones en producción:
- --maxbw=500000 limita el ancho de banda total utilizado por todos los procesos rsync, en KB/s. Útil cuando el enlace se comparte con otros servicios.
- --maxload=12 pausa el lanzamiento de nuevos procesos rsync una vez que la carga media del sistema supera el valor indicado. Útil en servidores de origen ocupados, pero consulte la advertencia siguiente antes de utilizarlo.
- --chunksize=5G controla el tamaño de cada chunk de fpart. Los chunks más grandes reducen la sobrecarga por chunk en transferencias con muchos archivos pequeños; los chunks más pequeños mejoran el paralelismo en transferencias con unos pocos archivos muy grandes.
- --rsyncopts="-a -s -x" permite pasar opciones adicionales directamente a los procesos rsync subyacentes. Úselo para habilitar la compresión (-z), establecer un tamaño de bloque personalizado o aplicar otros ajustes de rsync. No pase --delete a través de --rsyncopts; vea la sección "Limitaciones" más abajo para entender por qué no es seguro.
- --verbose=2 aumenta el detalle del registro, lo que facilita la resolución de problemas en las primeras ejecuciones.
El autor upstream ha documentado un problema conocido con --maxload: cuando parsyncfp pasa por ciclos repetidos de suspensión y reanudación, es posible que algunos archivos de origen no se transfieran al destino. Si utiliza --maxload, establezca el umbral lo suficientemente alto para que las suspensiones nunca se activen, o verifique el resultado con una comprobación de coherencia separada después de que finalice la transferencia.
Limitaciones
Incluso en hardware adecuado, parsyncfp tiene compromisos que conviene conocer antes de aumentar el número de procesos:
- parsyncfp no admite con seguridad la opción --delete de rsync. Cada proceso rsync paralelo ve sólo su propio bloque del origen, por lo que si se pasa --delete, todos los procesos intentarán eliminar archivos del destino que no estén en su bloque, lo que significa archivos que legítimamente pertenecen a otros bloques. Esto puede borrar grandes partes del destino. Use rsync simple (o una pasada de limpieza separada) cuando necesite la semántica de --delete.
- parsyncfp no preserva un ordenamiento global de los archivos entre los procesos rsync paralelos, por lo que el orden en el que los archivos aparecen en el destino no es predecible. Esto sólo importa para flujos de trabajo que dependen de las marcas de tiempo de los archivos o del orden de listado del directorio durante la propia copia.
- En matrices HDD, muchos procesos rsync paralelos convierten lo que sería un patrón de lectura secuencial en uno casi aleatorio, lo que puede ser más lento que un único rsync. Las unidades SSD y NVMe se ven mucho menos afectadas.
- En sistemas de archivos con un número muy grande de archivos pequeños, la sobrecarga de metadatos por archivo puede dominar el tiempo de transferencia. El paralelismo ayuda hasta cierto punto y luego se estanca.
- Cada proceso rsync abre su propia conexión SSH al destino, por lo que valores altos de --NP multiplican la sobrecarga de establecimiento de conexión. En enlaces WAN con pérdida de paquetes o alta latencia, esto puede empeorar la congestión en lugar de mejorarla. En ese caso, menos procesos con un rsync afinado (compresión, mayor tamaño de bloque) a menudo rinde mejor que muchos paralelos.
Véase también
Si parsyncfp resulta más pesado de lo que necesita, el paquete fpart también incluye fpsync, un wrapper paralelo de rsync más simple del mismo autor. Utiliza la misma idea de chunking pero con menos opciones y a menudo es suficiente para transferencias puntuales.