Sincronizar estructuras de carpetas muy grandes

14

Tenemos una estructura de carpetas en nuestra intranet que contiene alrededor de 800,000 archivos divididos en alrededor de 4,000 carpetas. Necesitamos sincronizar esto con un pequeño grupo de máquinas en nuestras DMZ. La profundidad de la estructura es muy superficial (nunca excede los dos niveles de profundidad).

La mayoría de los archivos nunca cambian, cada día hay unos pocos miles de archivos actualizados y 1-2 mil archivos nuevos. Los datos son datos de informes históricos que se mantienen donde se han purgado los datos de origen (es decir, estos son informes finalizados para los cuales los datos de origen son lo suficientemente antiguos como para archivarlos y eliminarlos). Sincronizar una vez al día es suficiente dado que puede suceder en un plazo razonable. Los informes se generan durante la noche y sincronizamos a primera hora de la mañana como una tarea programada.

Obviamente, dado que muy pocos de los archivos cambian regularmente, podemos beneficiarnos enormemente de la copia incremental. Hemos probado Rsync, pero eso puede llevar entre ocho y doce horas solo para completar la operación de "lista de archivos de construcción". Está claro que estamos superando rápidamente lo que rsync es capaz de hacer (el período de tiempo de 12 horas es demasiado largo).

Habíamos estado usando otra herramienta llamada RepliWeb para sincronizar las estructuras, y puede hacer una transferencia incremental en aproximadamente 45 minutos. Sin embargo, parece que hemos excedido su límite, ha comenzado a ver que los archivos se muestran como eliminaciones cuando no lo están (tal vez se haya agotado parte de la estructura de la memoria interna, no estamos seguros).

¿Alguien más se ha encontrado con un proyecto de sincronización a gran escala de este tipo? ¿Hay algo diseñado para manejar estructuras de archivos masivas como esta para la sincronización?

MightyE
fuente
¿Has intentado dividir el trabajo en varias instancias de rsync ejecutándose al mismo tiempo? No tengo una buena imagen de la estructura del directorio, pero podría dividirla por nombre de directorio o nombre de archivo.
Embrague
Habíamos pensado en eso, pero con una estructura tan plana, es difícil encontrar buenas líneas divisorias sobre las cuales dividir el trabajo. Es complicado por el hecho de que la mayoría de las carpetas tienen nombres muy similares (existe una convención de nomenclatura que hace que la mayoría de las carpetas comiencen con el mismo conjunto inicial de 6 caracteres).
MightyE
¿Alguna vez encontraste una buena solución, Dave? Estoy considerando lsyncd para un directorio con 65535 subdirectores, cada uno de los cuales podría tener 65 ^ 16 archivos.
Mike Diehn
1
@ MikeDiehn Nunca encontré una herramienta con la que estuviese totalmente feliz aquí. Obtuvimos esa herramienta patentada de RepliWeb para corregir el error donde veían archivos como eliminaciones que no lo eran, era una estructura interna desbordada. Dejé ese trabajo hace años, supongo que todavía lo están usando. Para sus propósitos, si sus directorios están razonablemente distribuidos, podría optar por algo como la solución de Ryan. No notará eliminaciones de nivel superior, pero 65535 subdirecciones me sugieren que probablemente no las tenga.
MightyE

Respuestas:

9

Si puede confiar en las marcas de tiempo modificadas por última vez en el sistema de archivos, puede acelerar las cosas combinando Rsync con la utilidad UNIX / Linux 'find'. 'find' puede armar una lista de todos los archivos que muestran los últimos tiempos modificados en el último día, y luego canalizar SOLAMENTE esa lista abreviada de archivos / directorios a Rsync. Esto es mucho más rápido que hacer que Rsync compare los metadatos de cada archivo en el remitente con el servidor remoto.

En resumen, el siguiente comando ejecutará Rsync SOLAMENTE en la lista de archivos y directorios que han cambiado en las últimas 24 horas: (Rsync NO se molestará en verificar otros archivos / directorios).

find /local/data/path/ -mindepth 1 -ctime -0 -print0 | xargs -0 -n 1 -I {} -- rsync -a {} remote.host:/remote/data/path/.

En caso de que no esté familiarizado con el comando 'buscar', se repite a través de un subárbol de directorio específico, buscando archivos y / o directorios que cumplan con los criterios que especifique. Por ejemplo, este comando:

find . -name '\.svn' -type d -ctime -0 -print

comenzará en el directorio actual (".") y recurrirá a todos los subdirectorios, buscando:

  • cualquier directorio ("-tipo d"),
  • llamado ".svn" ("-name '.svn'"),
  • con metadatos modificados en las últimas 24 horas ("-ctime -0").

Imprime el nombre de ruta completo ("-print") de cualquier cosa que coincida con esos criterios en la salida estándar. Las opciones '-name', '-type' y '-ctime' se llaman "pruebas", y la opción '-print' se llama "acción". La página del manual para 'buscar' tiene una lista completa de pruebas y acciones.

Si quiere ser realmente inteligente, puede usar la prueba '-cnewer' del comando 'find', en lugar de '-ctime' para hacer que este proceso sea más tolerante a fallas y flexible. '-cnewer' prueba si cada archivo / directorio en el árbol ha modificado sus metadatos más recientemente que algún archivo de referencia. Use 'tocar' para crear el archivo de referencia de la ejecución SIGUIENTE al comienzo de cada ejecución, justo antes de 'buscar ... | Se ejecuta el comando rsync ... '. Aquí está la implementación básica:

#!/bin/sh
curr_ref_file=`ls /var/run/last_rsync_run.*`
next_ref_file="/var/run/last_rsync_run.$RANDOM"
touch $next_ref_file
find /local/data/path/ -mindepth 1 -cnewer $curr_ref_file -print0 | xargs -0 -n 1 -I {} -- rsync -a {} remote.host:/remote/data/path/.
rm -f $curr_ref_file

Este script sabe automáticamente cuándo se ejecutó por última vez y solo transfiere archivos modificados desde la última ejecución. Si bien esto es más complicado, lo protege contra situaciones en las que podría haber perdido la ejecución del trabajo durante más de 24 horas, debido al tiempo de inactividad o algún otro error.

Ryan B. Lynch
fuente
¡Esta es una solución extremadamente inteligente! Estoy pensando que quieres decir al touch $next_ref_filefinal? Sin embargo, nos deja sin la capacidad de hacer frente a las rutas eliminadas (incluso estos informes de archivo estáticos eventualmente envejecen lo suficiente como para ser archivados y eliminados). Sin embargo, eso podría no ser un obstáculo para el espectáculo.
MightyE
Sin embargo, estoy descubriendo que incluso find . -ctime 0es bastante lento en esta estructura de directorios (todavía estoy esperando que se complete para informar su hora). Eso realmente me desanima un poco porque parece que esta podría ser una operación de nivel bastante bajo que probablemente establece el listón para lo más rápido que podríamos esperar que este trabajo se complete. Puede ser el caso de que la E / S de disco sea el factor limitante aquí.
MightyE
En cuanto a ese guión, sí, cometí un error. Me refería a ejecutar 'touch' en 'next_ref_file' (NO 'curr_ref_file') justo antes de ejecutar 'find ... | rsync ... 'comando. (Arreglaré mi respuesta.)
Ryan B. Lynch
3
En cuanto al lento comando 'buscar': ¿Qué tipo de sistema de archivos estás usando? Si está usando Ext3, es posible que desee considerar dos ajustes FS: 1) Ejecute 'tune2fs -O dir_index <DEVICE_NODE>' para habilitar la función 'dir_index' de Ext3, para acelerar el acceso a directorios con grandes cantidades de archivos. 2) Ejecute 'mount -o remontaje, noatime, nodiratime' para desactivar las actualizaciones de tiempo de acceso, que generalmente acelera la lectura. 'dumpe2fs -h <DEVICE_NODE> | grep dir_index 'le indica si' dir_index 'ya está habilitado (en algunas distribuciones, es el valor predeterminado) y' mount | grep <DEVICE_NODE> 'le informa sobre las actualizaciones de tiempo de acceso.
Ryan B. Lynch
Lamentablemente es NTFS: Windows 2003 Server utiliza Cygwin para el comando find. Recordaré esas opciones de ajuste (excelente consejo) para ext3 en caso de que alguna vez nos encontremos con algo similar en uno de nuestros clústeres de Debian.
MightyE
7

Pruebe al unísono , se diseñó específicamente para resolver este problema manteniendo las listas de cambios (lista de archivos de construcción), localmente para cada servidor, acelerando el tiempo para calcular el delta y la cantidad reducida que se envía a través del cable después.

Dave Cheney
fuente
Estoy probando a Unison. Se ha estado ejecutando durante aproximadamente 2 horas ahora en la etapa "Buscando cambios" y, según los archivos en los que está trabajando actualmente, parece que está casi a la mitad (por lo que tal vez 4 horas en total antes de que comience la transferencia). Parece que será mejor que rsync, pero aún fuera de nuestra ventana operativa deseada.
MightyE
2
La primera vez que crea un índice en ambos lados, los tiempos de reconstrucción son similares a rsync, ya que tiene que hacer hash en cada archivo. Una vez hecho esto, Unison utiliza la última hora modificada del directorio para identificar cuándo ha cambiado un archivo, y solo tiene que escanear ese archivo en busca de cambios.
Dave Cheney
Lamentablemente, fui víctima de un administrador de Operaciones demasiado entusiasta que finalizó forzosamente mi sesión antes de que se construyera el catálogo (limitamos la cantidad de inicios de sesión simultáneos en los servidores de producción). Perdí el progreso que había logrado en la construcción del catálogo inicial, así que tengo que comenzar de nuevo. Te diré cómo va.
MightyE
Tarda aproximadamente 2 horas ahora que el catálogo inicial está diseñado para buscar cambios. Estoy bastante sorprendido de la cantidad de RAM que Unison está usando para esto. Para nuestra colección de archivos, el servidor de origen usa 635M y el cliente remoto usa 366M. ¡Sincronizar varias máquinas en un clúster sería una huella bastante considerable, particularmente para el servidor de origen!
MightyE
1
¿Puede estructurar sus datos de una manera que facilite la identificación de los datos que ha cambiado recientemente? Es decir, ¿almacenarlo en formato año / mes / día / ...?
Dave Cheney
2

Si está utilizando el modificador -z en rsync, intente ejecutarlo sin él. Por alguna razón, he visto que esto acelera incluso la enumeración inicial de archivos.

Chris Thorpe
fuente
Hemos intentado con y sin la bandera -z. No pareció tener un impacto en la duración de la ejecución de la "lista de archivos de construcción".
MightyE
2

Al quitar -z del comando rsync, que no es compresión, la "lista de archivos de recepción" se hizo mucho más rápida y tuvimos que transferir unos 500 GB. Antes de que tomara un día con el modificador -z.

ryand32
fuente