rsync a múltiples destinos usando la misma lista de archivos?

22

Me pregunto si es posible que rsync copie un directorio a múltiples destinos remotos de una sola vez, o incluso en paralelo. (No es necesario, pero sería útil).

Normalmente, algo como lo siguiente funcionaría bien:

$ rsync -Pav /junk user@host1:/backup
$ rsync -Pav /junk user@host2:/backup
$ rsync -Pav /junk user@host3:/backup

Y si esa es la única opción, la usaré. Sin embargo, / junk se encuentra en un disco lento con bastantes archivos, y la reconstrucción de la lista de archivos de unos ~ 12,000 archivos cada vez es extremadamente lenta (~ 5 minutos) en comparación con la transferencia / actualización real. ¿Es posible hacer algo como esto, lograr lo mismo:

$ rsync -Pav /junk user@host1:/backup user@host2:/backup user@host3:/backup 

¡Gracias por mirar!

Jessie
fuente

Respuestas:

12

Aquí está la información de la página del manual para rsync sobre el modo por lotes.

POR LOTES

El modo por lotes se puede usar para aplicar el mismo conjunto de actualizaciones a muchos sistemas idénticos. Supongamos que uno tiene un árbol que se replica en varios hosts. Ahora suponga que se han realizado algunos cambios en este árbol de origen y esos cambios deben propagarse a los otros hosts. Para hacer esto usando el modo por lotes, rsync se ejecuta con la opción de escritura por lotes para aplicar los cambios realizados en el árbol de origen a uno de los árboles de destino. La opción de escritura por lotes hace que el cliente rsync almacene en un "archivo por lotes" toda la información necesaria para repetir esta operación contra otros árboles de destino idénticos.

Generar el archivo por lotes una vez ahorra tener que realizar el estado del archivo, la suma de verificación y la generación del bloque de datos más de una vez al actualizar varios árboles de destino. Los protocolos de transporte de multidifusión se pueden usar para transferir los archivos de actualización por lotes en paralelo a muchos hosts a la vez, en lugar de enviar los mismos datos a cada host individualmente.

Para aplicar los cambios registrados a otro árbol de destino, ejecute rsync con la opción de lectura por lotes, especificando el nombre del mismo archivo por lotes y el árbol de destino. Rsync actualiza el árbol de destino utilizando la información almacenada en el archivo por lotes.

Para su comodidad, también se crea un archivo de secuencia de comandos cuando se utiliza la opción de escritura por lotes: se denominará igual que el archivo por lotes con ".sh" adjunto. Este archivo de script contiene una línea de comandos adecuada para actualizar un árbol de destino utilizando el archivo por lotes asociado. Se puede ejecutar utilizando un shell Bourne (o similar a Bourne), opcionalmente pasando un nombre de ruta de árbol de destino alternativo que luego se usa en lugar de la ruta de destino original. Esto es útil cuando la ruta del árbol de destino en el host actual difiere de la utilizada para crear el archivo por lotes.

   Examples:

          $ rsync --write-batch=foo -a host:/source/dir/ /adest/dir/
          $ scp foo* remote:
          $ ssh remote ./foo.sh /bdest/dir/

          $ rsync --write-batch=foo -a /source/dir/ /adest/dir/
          $ ssh remote rsync --read-batch=- -a /bdest/dir/ <foo

En estos ejemplos, rsync se usa para actualizar / adest / dir / from / source / dir / y la información para repetir esta operación se almacena en "foo" y "foo.sh". El host "remoto" se actualiza con los datos por lotes que van al directorio / bdest / dir. Las diferencias entre los dos ejemplos revelan algo de la flexibilidad que tiene en la forma en que maneja los lotes:

  • El primer ejemplo muestra que la copia inicial no tiene que ser local: puede insertar o extraer datos hacia / desde un host remoto utilizando la sintaxis de shell remoto o la sintaxis de demonio rsync, según lo desee.

  • El primer ejemplo utiliza el archivo "foo.sh" creado para obtener las opciones correctas de rsync cuando ejecuta el comando read-batch en el host remoto.

  • El segundo ejemplo lee los datos del lote a través de la entrada estándar para que el archivo del lote no necesite copiarse primero en la máquina remota. Este ejemplo evita el script foo.sh porque necesitaba usar una opción modificada --read-batch, pero podría editar el archivo de script si desea utilizarlo (solo asegúrese de que ninguna otra opción intente usar el estándar entrada, como la opción "--exclude-from = -").

    Advertencias:

    La opción de lectura por lotes espera que el árbol de destino que está actualizando sea idéntico al árbol de destino que se utilizó para crear el conjunto de archivos de actualización por lotes. Cuando se encuentra una diferencia entre los árboles de destino, la actualización puede descartarse con una advertencia (si el archivo parece estar ya actualizado) o puede intentarse la actualización del archivo y luego, si el archivo no se verifica , la actualización se descartó con un error. Esto significa que debería ser seguro volver a ejecutar una operación de lectura por lotes si el comando se interrumpió. Si desea forzar que siempre se intente la actualización por lotes, independientemente del tamaño y la fecha del archivo, use la opción -I (al leer el lote). Si se produce un error, el árbol de destino probablemente estará en un estado parcialmente actualizado. En ese caso,

    La versión rsync utilizada en todos los destinos debe ser al menos tan nueva como la utilizada para generar el archivo por lotes. Rsync morirá con un error si la versión del protocolo en el archivo por lotes es demasiado nueva para que la rsync de lectura por lotes pueda manejarla. Consulte también la opción --protocol para obtener una manera de que la creación de rsync genere un archivo por lotes que una rsync más antigua puede comprender. (Tenga en cuenta que los archivos por lotes cambiaron de formato en la versión 2.6.3, por lo que no funcionará mezclar versiones anteriores a las nuevas).

    Al leer un archivo por lotes, rsync forzará el valor de ciertas opciones para que coincidan con los datos del archivo por lotes si no los configuró de la misma manera que el comando de escritura por lotes. Otras opciones pueden (y deberían) cambiarse. Por ejemplo, --write-batch cambia a --read-batch, --files-from se descarta, y las opciones --filter / - include / - exclude no son necesarias a menos que se especifique una de las opciones --delete .

    El código que crea el archivo BATCH.sh transforma cualquier opción de filtro / inclusión / exclusión en una lista única que se agrega como un documento "aquí" al archivo de script de shell. Un usuario avanzado puede usar esto para modificar la lista de exclusión si se desea un cambio en lo que se elimina por --delete. Un usuario normal puede ignorar este detalle y simplemente usar el script de shell como una forma fácil de ejecutar el comando --read-batch apropiado para los datos por lotes.

    El modo por lotes original en rsync se basaba en "rsync +", pero la última versión usa una nueva implementación.

Me imagino que podrías intentar

rsync --write-batch=foo -Pav /junk user@host1:/backup
foo.sh user@host2:/backup
foo.sh user@host3:/backup
Chloe
fuente
El comando sugerido no funciona:remote destination is not allowed with --read-batch
kynan
Mostrar el comando completo. -para un nombre de archivo significa leer de la entrada estándar, y STDIN también se lee fooen el ejemplo, un archivo local.
Chloe
2
Esta parece ser la solución máximamente correcta para lo que estaba tratando de hacer, aunque mi caso de uso para esto se ha evaporado hace mucho tiempo en el éter. : D
Jessie
4

Podrías intentar usar unísono . Debería ser mucho más rápido en la construcción de la lista de archivos porque mantiene un caché de los archivos.

Jason Axelson
fuente
2
Nota: Unison no mantiene un 'caché' de los archivos. Solo mantiene una base de datos de los nombres de archivo, marcas de tiempo, sumas de verificación. Todavía escanea el sistema de archivos y crea una suma de verificación para comparar con el control remoto. La única ventaja de Unison es la sincronización bidireccional. Recomiendo Unison, pero no ayudará aquí.
Chloe
4

El rsync --batch-modesoporta multicast. Si esto es posible en su red, podría valer la pena investigarlo.

codecrank
fuente
2

¿Qué hay de cambiar los sistemas de archivos?

Hace algún tiempo, cambié un FS de varios terabytes de ext3 a XFS. ¡El tiempo para escanear los directorios (con alrededor de 600,000 archivos la última vez que revisé) pasó de 15-17 minutos a menos de 30 segundos!

Javier
fuente
1

No es una respuesta directa, pero si utiliza rsync versión 3+, comenzará a transferirse antes de generar la lista de archivos completa.

Otra opción, aún no muy eficiente, sería ejecutarlos como trabajos, por lo que algunos se ejecutan al mismo tiempo.

Además, solo pensé en esta estrangulación si no te importa usar tar:

tar cf - . | tee >(ssh localhost 'cat > test1.tar') >(ssh localhost 'cat > test2.tar') >/dev/null

Donde cada host local sería servidores diferentes, por supuesto (supone un inicio de sesión basado en claves). Sin embargo, nunca he usado lo anterior.

Kyle Brandt
fuente
Hmm! Por extraño que parezca, cwrsync (rsync 3.0.7) parece no hacer eso. Sin embargo, tendré que investigar por qué es así, ya que sería una gran ayuda para reducir estos enormes tiempos de ejecución. ¡Gracias!
Jessie
Esa versión en ambos lados?
Kyle Brandt
No actualmente; la máquina local es cwrsync 3.0.7 y el host remoto (bueno, con el que estoy trabajando ahora) es rsync 3.0.3 en Debian Lenny. No parece que sea una diferencia de versión demasiado grande para que se comporte mal, pero no sé ... buscaré actualizar el lado de Debian.
Jessie
1
Qué pequeña y extraña frase. Sin embargo, eso probablemente funcionaría si no aprovechara el hecho de que rsync no necesita reducir la duplicación de algunos datos en varios enlaces lentos cuando, como máximo, solo unos pocos cientos de kb han cambiado. Además, obtener ambos extremos para (cw) rsync 3.0.7 todavía hizo la creación de listas de archivos y la transferencia en serie. Sin embargo, no estoy demasiado preocupado por eso.
Jessie
No es "tar cf -". lo mismo que "alquitrán c". ?
Johan Boulé
1

¿Qué tal si ejecuta los trabajos rsync desde host1, host2 y host3? O bien, ejecute un trabajo para copiar en host1 y luego ejecútelo en host2 y host3 para obtenerlo desde host1.

mfinni
fuente
1

Una mejor solución sería crear un repositorio con git y simplemente presionar a los 3 hosts. Más rápido, no necesitaría la parte de la lista de archivos y consume menos recursos.

Buena suerte,
João Miguel Neves.

jneves
fuente
10
git no conserva los tiempos de modificación ni los permisos (excepto el bit de ejecución) y requeriría almacenar una segunda copia de los datos como objetos de git, .git/aunque los empujes a los controles remotos que ya tendrían la mayoría de los datos serían más rápidos. git no es un reemplazo para rsync.
Dan D.
Además, git se puede ver públicamente, a menos que pague.
Chloe
8
@Chloe, confundes git con GitHub. Git en sí es un sistema de control de versiones distribuido de código abierto gratuito, y cualquiera puede alojar el repositorio de git por cualquier medio, incluidos http, nfsy afp. GitHub es un sitio web que se encarga de crear y mantener repositorios git para usted, y los hace públicos (a menos que pague).
toriningen
1
@Chloe GitHub se puede ver públicamente, pero BitBucket proporciona repositorios privados.
sws
2
Además, Git no realiza un seguimiento de los directorios vacíos.
Flimm
1

Al buscar esta respuesta por mí mismo, creo que primero deberías hacer un lote usando rsync y luego enviárselo a todos, lo que haría que la lista de archivos tuviera que ser procesada solo una vez, y luego podrías simplemente fondo los tres rsyncs para ejecutarlos en paralelo.

Morgan
fuente
1

Otra posible solución es ejecutar tantos procesos rsync en paralelo como hosts, es decir, fork.

Alexey Tigarev
fuente