¿Opciones para sincronizar eficientemente 1 millón de archivos con servidores remotos?

27

En una empresa para la que trabajo, tenemos algo llamado "listas de reproducción", que son archivos pequeños de ~ 100-300 bytes cada uno. Hay alrededor de un millón de ellos. Alrededor de 100,000 de ellos se cambian cada hora. Estas listas de reproducción deben cargarse en otros 10 servidores remotos en diferentes continentes cada hora y lo ideal es que suceda rápidamente en menos de 2 minutos. Es muy importante que los archivos que se eliminan en el maestro también se eliminen en todas las réplicas. Actualmente usamos Linux para nuestra infraestructura.

Estaba pensando en probar rsync con la opción -W para copiar archivos completos sin comparar contenidos. Todavía no lo he probado, pero tal vez las personas que tienen más experiencia con rsync podrían decirme si es una opción viable.

¿Qué otras opciones vale la pena considerar?

Actualización: elegí la opción lsyncd como respuesta, pero solo porque era la más popular. Otras alternativas sugeridas también son válidas a su manera.

Zilvinas
fuente
1
¿Tiene un registro que indica qué archivos se han cambiado o eliminado?
Oliver
3
Si solo las listas de reproducción fueran registros mysql. Luego, podría usar la replicación de la base de datos y obtener mysql para resolver lo que se necesita para ser enviado / recibido.
Matt
@oliver lo hacemos. Sin embargo, debe confiar en ese registro, lo que significa que el código que lo genera debe ser correcto y luego necesita un código personalizado para procesar ese registro, que también debe ser correcto. Prefiero evitar el código interno para hacerlo sobre algo que ha sido ampliamente probado por la comunidad.
Zilvinas
¿Desea que el cambio solo se aplique cada hora? ¿O también es aceptable la replicación instantánea?
falsificador
1
No subestimes el tiempo que le lleva a rsync trabajar con un millón de archivos. Solo pruébalo y verás lo que estás haciendo. Si tiene ese registro, úselo o pruebe alguna de las soluciones propuestas.
Oliver

Respuestas:

39

Como las actualizaciones instantáneas también son aceptables, puede usar lsyncd .
Observa directorios (inotify) y rsynccambiará a esclavos.
Al inicio, hará un completo rsync, por lo que tomará un tiempo, pero después de eso solo se transmiten los cambios.
La visualización recursiva de directorios es posible, si un servidor esclavo está inactivo, la sincronización se volverá a intentar hasta que vuelva.

Si todo esto está en un solo directorio (o una lista estática de directorios), también puede usar incron .
El inconveniente es que no permite la observación recursiva de carpetas y debe implementar la funcionalidad de sincronización usted mismo.

falsificador
fuente
De nuevo un consejo brillante :)
Zilvinas
1
+1 Esto es esencialmente un problema de coherencia de caché, un monitor que impulsa los cambios es la solución más fácil. lsyncdimplementa eso ...
Chris S
1
Investigaría lsyncdy inotifyprofundamente según se aplique a su sistema operativo de servidor específico. Hay un límite en la cantidad de relojes inotify disponibles. Creo que el valor predeterminado es alrededor de 1500 u 8000 dependiendo de su versión particular de Linux. La mayoría de los núcleos le permiten elevar el límite, pero monitorear 1 millón de archivos puede ser más de lo práctico. No funcionó para mí en 2008. Además, la cola de eventos de inotify puede desbordarse y provocar la pérdida de eventos, y debe tener una forma de recuperarse de eso. Una lsyncdimplementación cuidadosamente ajustada más un diario rsyncpodría funcionar ahora en 2012 para cubrir sus bases.
Old Pro
2
En realidad, hace un iontifyen el directorio no los archivos individuales. ¿Cuántos directorios puedes ver? Comprobar /proc/sys/fs/inotify/max_user_watches(generalmente 8192).
falsificador
2
Con ~ 50k directorios, inotify posiblemente no escalará bien. Cuando probamos un enfoque similar en 2009 con 100k directorios, el núcleo tardó mucho en suscribirse a todos los directorios. En cuanto a @OldPro, no funcionó para nosotros.
neovatar
11

Considere usar un sistema de archivos distribuido, como GlusterFS . Al estar diseñado teniendo en cuenta la replicación y el paralelismo, GlusterFS puede escalar hasta 10 servidores mucho más fácilmente que las soluciones ad-hoc que implican inotify y rsync.

Para este caso de uso en particular, se podría construir un volumen GlusterFS de 10 servidores de 10 réplicas (es decir, 1 réplica / ladrillo por servidor), de modo que cada réplica sea un espejo exacto de todas las demás réplicas en el volumen. GlusterFS propagaría automáticamente las actualizaciones del sistema de archivos a todas las réplicas.

Los clientes en cada ubicación se pondrían en contacto con su servidor local, por lo que el acceso de lectura a los archivos sería rápido. La pregunta clave es si la latencia de escritura podría mantenerse aceptablemente baja. La única forma de responder eso es probarlo.

Steven Monday
fuente
+1 para Glusterfs
Tom O'Connor
8

Dudo rsyncque funcione para esto de la manera normal, porque escanear un millón de archivos y compararlo con el sistema remoto 10 veces tomaría mucho tiempo. Intentaría implementar un sistema con algo así inotifyque mantenga una lista de archivos modificados y los envíe a los servidores remotos (de todos modos, si estos cambios no se registran de otra manera). Luego puede usar esta lista para identificar rápidamente los archivos que se deben transferir, tal vez incluso con rsync (o mejores 10 instancias paralelas de la misma).

Editar: con un poco de trabajo, incluso podría usar este enfoque de inotify / log watch para copiar los archivos tan pronto como ocurra la modificación.

Sven
fuente
5

Algunas alternativas más:

  • Inserte un trabajo en RabbitMQ o Gearman para apagar y eliminar asincrónicamente (o agregar) el mismo archivo en todos los servidores remotos cada vez que elimine o agregue un archivo en el servidor primario.
  • Almacene los archivos en una base de datos y use la replicación para mantener sincronizados los servidores remotos.
  • Si tiene ZFS , puede usar la replicación ZFS .
  • Algunas SAN tienen replicación de archivos. No tengo idea si esto se puede usar a través de Internet.
Ladadadada
fuente
4

Este parece ser un caso de uso ideal del libro de cuentos para MongoDB y tal vez GridFS . Como los archivos son relativamente pequeños, MongoDB solo debería ser suficiente, aunque puede ser conveniente usar la API de GridFS.

MongoDB es una base de datos nosql y GridFS es una compilación de almacenamiento de archivos. MongoDB tiene muchas opciones integradas para replicación y fragmentación , por lo que debería escalar muy bien en su caso de uso.

En su caso, probablemente comenzará con un conjunto de réplicas que consiste en el maestro ubicado en su centro de datos primario (tal vez un segundo, en caso de que desee realizar una conmutación por error en la misma ubicación) y sus diez "esclavos" distribuidos por todo el mundo. Luego realice pruebas de carga para verificar si el rendimiento de escritura es suficiente y verifique los tiempos de replicación en sus nodos. Si necesita más rendimiento, puede convertir la configuración en fragmentada (principalmente para distribuir la carga de escritura a más servidores). MongoDB ha sido diseñado para escalar configuraciones enormes con hardware "barato", para que pueda agregar un lote de servidores económicos para mejorar el rendimiento.

neovatar
fuente
0

Usaría un S3 Backend y luego lo montaría en todos los servidores que necesito. De esa forma, todos se sincronizarán instantáneamente de todos modos

Señor IT Guru
fuente
Si bien el almacenamiento se sincronizaría, tendría que notificar a la aplicación, por lo que volvería al punto de partida, o la aplicación tendría que sondear el almacenamiento cada vez que alguien acceda a estas listas de reproducción. El rendimiento sería horrible en cualquier caso.
Chris S
La aplicación no necesita sondear el almacenamiento cada vez que alguien accede a las listas de reproducción, solo lo suficiente en una hora para garantizar que la aplicación se ejecute sin datos obsoletos. Además, si S3 se usa como back-end, ¿por qué la aplicación necesitaría sondear los archivos en primer lugar? Siempre estarán actualizados
Mister IT Guru
0

Una opción que no parece haberse mencionado aún es archivar todos los archivos en un archivo comprimido. Esto debería reducir el tamaño total de manera significativa y eliminar toda la sobrecarga que se obtiene al tratar con millones de archivos individuales. Al reemplazar todo el conjunto de archivos en una gran actualización, también puede estar seguro de que los archivos eliminados se eliminan en las réplicas.

La desventaja es, por supuesto, que está transfiriendo muchos archivos innecesariamente. Eso puede o no compensarse con el tamaño reducido gracias a la compresión. Tampoco tengo idea de cuánto tiempo tomaría comprimir tantos archivos.

Supr
fuente