
Estimada comunidad, este artículo se centrará en el almacenamiento eficiente y la entrega de cientos de millones de archivos pequeños. En esta etapa, se propone la solución final para sistemas de archivos compatibles con POSIX con soporte completo para bloqueos, incluidos los de clúster, e incluso sin muletas.
Por lo tanto, para este propósito escribí mi propio servidor especializado.
En el curso de esta tarea, fue posible resolver el problema principal, en el camino para ahorrar espacio en disco y RAM, que nuestro sistema de archivos del clúster consumió sin piedad. En realidad, tal cantidad de archivos es perjudicial para cualquier sistema de archivos en clúster.
La idea es esta:
En palabras simples, los archivos pequeños se cargan a través del servidor, se guardan directamente en el archivo y también se leen, y los archivos grandes se colocan cerca. Esquema: 1 carpeta = 1 archivo, en total tenemos varios millones de archivos con archivos pequeños, y no varios cientos de millones de archivos. Y todo esto está completamente implementado, sin scripts y archivos plegables en archivos tar / zip.
Intentaré acortarlo, me disculpo de antemano si la publicación será amplia.
Todo comenzó con el hecho de que no pude encontrar un servidor adecuado en el mundo que pudiera guardar los datos recibidos a través del protocolo HTTP directamente en los archivos, por lo que no hubo inconvenientes inherentes a los archivos ordinarios y repositorios de objetos. Y la razón de la búsqueda fue un grupo de 10 servidores que crecieron a un origen de gran escala, en el que ya se habían acumulado 250,000,000 de archivos pequeños, y la tendencia de crecimiento no iba a detenerse.
Aquellos a quienes no les gusta leer artículos y un poco de documentación es más fácil:aquí y
aquíActualización Se eliminó nginx de la imagen del acoplador.Y docker al mismo tiempo:
docker run -d --restart=always -e bindaddr=127.0.0.1:9699 \ -e host=localhost -e root=/var/storage -v /var/storage:/var/storage --name wzd \ -p 80:9699 eltaline/wzd
Siguiente:
Actualización En la versión 1.1.0, ya apareció el método de autenticación HTTPS / POST / IP, etc.Si hay muchos archivos, se necesitan recursos significativos y, lo que es más ofensivo, algunos de ellos se desperdician. Por ejemplo, cuando se utiliza un sistema de archivos en clúster (en este caso, MooseFS), un archivo, independientemente del tamaño real, siempre ocupa al menos 64 KB. Es decir, para archivos de 3, 10 o 30 KB de tamaño, se requieren 64 KB en el disco. Si un cuarto de billón de archivos, perdemos de 2 a 10 terabytes. No será posible crear nuevos archivos hasta el infinito ya que existe una limitación en el propio MooseFS: no más de mil millones con una réplica de cada archivo.
A medida que aumenta el número de archivos, necesita mucha RAM para los metadatos. Los volcados de metadatos grandes frecuentes también contribuyen al desgaste de los SSD.
Servidor WZD. Ponemos los discos en orden.El servidor está escrito en Go. En primer lugar, necesitaba reducir la cantidad de archivos. Como hacerlo Debido al archivo, pero en este caso sin compresión, ya que mis archivos son imágenes sólidas y recortadas. BoltDB vino al rescate, que aún tenía que ser privado de fallas, esto se refleja en la documentación.
En total, en lugar de un cuarto de billón de archivos, en mi caso solo quedaron 10 millones de archivos de Bolt. Si tuviera la oportunidad de cambiar la estructura actual de llenar archivos de directorio, entonces sería posible reducir a aproximadamente 1 millón de archivos.
Todos los archivos pequeños se empaquetan en archivos Bolt, reciben automáticamente los nombres de los directorios en los que se encuentran, y todos los archivos grandes permanecen al lado de los archivos, no tiene sentido empacarlos, esto es personalizable. Pequeño - archivo, grande - dejar sin cambios. El servidor funciona de forma transparente con ambos.
Arquitectura y características del servidor wZD.
El servidor ejecuta Linux, BSD, Solaris y OSX. Probé solo la arquitectura AMD64 en Linux, pero también debería ser adecuada para ARM64, PPC64, MIPS64.
Características clave:- Multihilo;
- Multi-servidor, proporcionando tolerancia a fallas y balanceo de carga;
- Máxima transparencia para el usuario o desarrollador;
- Métodos HTTP admitidos: GET, HEAD, PUT y DELETE;
- Gestión del comportamiento de lectura y escritura a través de encabezados de clientes;
- Soporte para hosts virtuales personalizables;
- Admite integridad de datos CRC al escribir / leer;
- Memorias intermedias semidinámicas para un consumo mínimo de memoria y un ajuste óptimo del rendimiento de la red;
- Compactación de datos retrasada
- Además, se ofrece un archivador wZA multiproceso para la migración de archivos sin detener el servicio.
Experiencia real:He estado desarrollando y probando el servidor y el archivador en datos en vivo durante bastante tiempo, ahora funciona con éxito en un clúster que incluye 250,000,000 de pequeños archivos (imágenes) ubicados en 15,000,000 de directorios en discos SATA separados. Un clúster de 10 servidores es un servidor Origin instalado detrás de una red CDN. Para su mantenimiento, se utilizan 2 servidores Nginx + 2 servidores wZD.
Para aquellos que deciden usar este servidor, tiene sentido planificar la estructura del directorio antes de usar, si corresponde. Inmediatamente haga una reserva de que el servidor no está diseñado para insertar todo en el archivo 1 Bolt.
Pruebas de rendimiento:Cuanto menor sea el tamaño del archivo archivado, más rápido se realizarán las operaciones GET y PUT en él. Compare el tiempo total que el cliente HTTP escribe en archivos normales y en archivos Bolt, y también lee. Compara el trabajo con archivos de 32 KB, 256 KB, 1024 KB, 4096 KB y 32768 KB de tamaño.
Cuando se trabaja con archivos Bolt, se verifica la integridad de los datos de cada archivo (se usa CRC), antes de escribir y también después de escribir, la lectura se realiza sobre la marcha y el recuento, esto naturalmente presenta demoras, pero lo principal es la seguridad de los datos.
Realicé pruebas de rendimiento en SSD, ya que en los discos SATA las pruebas no muestran una diferencia clara.
Actualización (v1.1.0), rendimiento mejorado en un 5-25%.Gráficos basados en resultados de pruebas:

Como puede ver, para archivos pequeños, la diferencia en el tiempo de lectura y escritura entre archivos archivados y no archivados es pequeña.
Obtendremos una imagen completamente diferente con la prueba de leer y escribir archivos de 32 MB:

La diferencia horaria entre la lectura de archivos es de 5 a 25 ms. Con la grabación, las cosas son peores, la diferencia es de unos 150 ms. Pero en este caso, no es necesario cargar archivos grandes, esto simplemente no tiene sentido, pueden vivir separados de los archivos.
* Técnicamente, este servidor también se puede utilizar para tareas que requieren NoSQL.
Métodos básicos de trabajo con el servidor wZD:Descargar archivo regular:
curl -X PUT --data-binary @test.jpg http://localhost/test/test.jpg
Cargar un archivo en el archivo Bolt (si no se excede el parámetro del servidor fmaxsize, que determina el tamaño máximo de archivo que se puede incluir en el archivo, si se excede, el archivo se cargará como siempre al lado del archivo):
curl -X PUT -H "Archive: 1" --data-binary @test.jpg http://localhost/test/test.jpg
Descargar un archivo (si hay archivos con el mismo nombre en el disco y en el archivo comprimido, entonces, al descargar, se le da prioridad al archivo descomprimido):
curl -o test.jpg http://localhost/test/test.jpg
Descargar un archivo del archivo Bolt (forzado):
curl -o test.jpg -H "FromArchive: 1" http://localhost/test/test.jpg
Una descripción de otros métodos está en la documentación.
Documentación WZDDocumentación de WZAHasta ahora, el servidor solo admite HTTP, todavía no funciona con HTTPS. El método POST tampoco es compatible (aún no se ha decidido si es necesario o no).
Cualquiera que profundice en el código fuente encontrará un caramelo allí, no a todos les encanta, pero no vinculé el código principal a las funciones del marco web, excepto el controlador de interrupciones, para que en el futuro pueda reescribir rápidamente a casi cualquier motor.
Tarea:- Desarrollo de nuestro propio replicador y distribuidor + geo para la posibilidad de uso en sistemas grandes sin FS grupales (Todo para un adulto)
- La capacidad de revertir completamente los metadatos de restauración cuando se pierde por completo (si usa un distribuidor)
- Protocolo nativo para la posibilidad de usar conexiones de red permanentes y controladores para diferentes lenguajes de programación
- Características avanzadas del uso del componente NoSQL
- Compresiones de diferentes tipos (gzip, zstd, snappy) para archivos o valores dentro de archivos Bolt y para archivos ordinarios
- Cifrado de diferentes tipos para archivos o valores dentro de archivos Bolt y para archivos ordinarios
- Conversión de video de servidor retrasada, incluida GPU
Eso es todo, espero que este servidor sea útil para alguien, licencia BSD-3, doble derecho de autor, ya que no habría una compañía donde yo trabajara, tampoco escribiría un servidor. Soy un desarrollador en singular. Agradecería los errores encontrados y las solicitudes de funciones.