Almacena de forma eficiente centos de millóns de ficheiros pequenos. Solución autoaloxada

Almacena de forma eficiente centos de millóns de ficheiros pequenos. Solución autoaloxada

Estimada comunidade, este artigo centrarase en almacenar e recuperar de forma eficiente centos de millóns de ficheiros pequenos. Nesta fase, proponse a solución final para sistemas de ficheiros compatibles con POSIX con soporte total para bloqueos, incluíndo bloqueos de clúster, e aparentemente mesmo sen muletas.

Entón escribín o meu propio servidor personalizado para este propósito.
Durante a implementación desta tarefa, conseguimos resolver o problema principal e, ao mesmo tempo, conseguir un aforro de espazo en disco e RAM, que o noso sistema de ficheiros de clúster consumía sen piedade. En realidade, tal número de ficheiros é prexudicial para calquera sistema de ficheiros agrupado.

A idea é esta:

En palabras simples, os ficheiros pequenos cárganse a través do servidor, gárdanse directamente no arquivo e tamén se len a partir del, e os ficheiros grandes colócanse un ao carón. Esquema: 1 cartafol = 1 arquivo, en total temos varios millóns de arquivos con ficheiros pequenos, e non varios centos de millóns de ficheiros. E todo isto está implementado completamente, sen scripts nin poñer ficheiros en arquivos tar/zip.

Tentarei ser breve, pido desculpas de antemán se a publicación é longa.

Todo comezou co feito de que non puiden atopar un servidor axeitado no mundo que puidese gardar os datos recibidos a través do protocolo HTTP directamente en arquivos, sen as desvantaxes inherentes aos arquivos convencionais e ao almacenamento de obxectos. E o motivo da busca foi o clúster Origin de 10 servidores que creceu a gran escala, no que xa se acumularon 250,000,000 de pequenos ficheiros, e a tendencia de crecemento non ía parar.

Para os que non lles gusta ler artigos, un pouco de documentación é máis fácil:

aquí и aquí.

E docker ao mesmo tempo, agora hai unha opción só con nginx dentro por se acaso:

docker run -d --restart=always -e host=localhost -e root=/var/storage 
-v /var/storage:/var/storage --name wzd -p 80:80 eltaline/wzd

Seguinte:

Se hai moitos ficheiros, necesítanse recursos importantes, e o peor é que algúns se desperdician. Por exemplo, cando se usa un sistema de ficheiros agrupado (neste caso, MooseFS), o ficheiro, independentemente do seu tamaño real, ocupa sempre polo menos 64 KB. É dicir, para ficheiros de 3, 10 ou 30 KB de tamaño son necesarios 64 KB en disco. Se hai un cuarto de billón de ficheiros, perdemos de 2 a 10 terabytes. Non será posible crear novos ficheiros indefinidamente, xa que MooseFS ten unha limitación: non máis de 1 millóns cunha réplica de cada ficheiro.

A medida que aumenta o número de ficheiros, necesítase moita memoria RAM para os metadatos. Os grandes volcados de metadatos frecuentes tamén contribúen ao desgaste das unidades SSD.

servidor wZD. Poñemos as cousas en orde nos discos.

O servidor está escrito en Go. En primeiro lugar, necesitaba reducir o número de ficheiros. Como facelo? Debido ao arquivo, pero neste caso sen compresión, xa que os meus ficheiros son só imaxes comprimidas. BoltDB acudiu ao rescate, que aínda tiña que ser eliminado das súas deficiencias, así se reflicte na documentación.

En total, en lugar de un cuarto de billón de arquivos, no meu caso só quedaban 10 millóns de arquivos Bolt. Se tivese a oportunidade de cambiar a estrutura de ficheiros do directorio actual, sería posible reducila a aproximadamente 1 millón de ficheiros.

Todos os ficheiros pequenos están empaquetados en arquivos Bolt, que reciben automaticamente os nomes dos directorios nos que se atopan, e todos os ficheiros grandes permanecen xunto aos arquivos; non ten sentido empaquetalos, isto é personalizable. Os pequenos arquivanse, os grandes non se modifican. O servidor funciona de forma transparente con ambos.

Arquitectura e características do servidor wZD.

Almacena de forma eficiente centos de millóns de ficheiros pequenos. Solución autoaloxada

O servidor funciona baixo os sistemas operativos Linux, BSD, Solaris e OSX. Só probei a arquitectura AMD64 en Linux, pero debería funcionar para ARM64, PPC64, MIPS64.

Principais características:

  • Multithreading;
  • Multiservidor, proporcionando tolerancia a fallos e equilibrio de carga;
  • Máxima transparencia para o usuario ou desenvolvedor;
  • Métodos HTTP admitidos: GET, HEAD, PUT e DELETE;
  • Control do comportamento de lectura e escritura a través das cabeceiras do cliente;
  • Soporte para hosts virtuais flexibles;
  • Admite a integridade dos datos CRC ao escribir/ler;
  • Buffers semi-dinámicos para un consumo mínimo de memoria e unha optimización do rendemento da rede;
  • Compactación de datos diferida;
  • Ademais, ofrécese un arquivador multiproceso wZA para migrar ficheiros sen deter o servizo.

Experiencia real:

Estiven desenvolvendo e probando o servidor e o arquivador en datos en directo durante bastante tempo, agora está a funcionar con éxito nun clúster que inclúe 250,000,000 de ficheiros pequenos (imaxes) situados en 15,000,000 de directorios en unidades SATA separadas. Un clúster de 10 servidores é un servidor Origin instalado detrás dunha rede CDN. Para atendelo, utilízanse 2 servidores Nginx + 2 servidores wZD.

Para aqueles que decidan usar este servidor, sería conveniente planificar a estrutura do directorio, se é o caso, antes do uso. Permítanme facer unha reserva de inmediato para indicar que o servidor non está destinado a meter todo nun arquivo 1 Bolt.

Probas de rendemento:

Canto menor sexa o tamaño do ficheiro comprimido, máis rápido se realizan as operacións GET e PUT. Comparemos o tempo total de escritura do cliente HTTP con ficheiros normais e arquivos Bolt, así como a lectura. Compárase o traballo con ficheiros de tamaños de 32 KB, 256 KB, 1024 KB, 4096 KB e 32768 KB.

Cando se traballa con arquivos Bolt, compróbase a integridade dos datos de cada ficheiro (utilízase CRC), antes da gravación e tamén despois da gravación, prodúcese a lectura e o recálculo ao voo, isto naturalmente introduce atrasos, pero o principal é a seguridade dos datos.

Fixen probas de rendemento en unidades SSD, xa que as probas en unidades SATA non mostran unha diferenza clara.

Gráficos baseados nos resultados das probas:

Almacena de forma eficiente centos de millóns de ficheiros pequenos. Solución autoaloxada
Almacena de forma eficiente centos de millóns de ficheiros pequenos. Solución autoaloxada

Como podes ver, para ficheiros pequenos a diferenza de tempos de lectura e escritura entre ficheiros arquivados e non arquivados é pequena.

Obtemos unha imaxe completamente diferente ao probar a lectura e a escritura de ficheiros de 32 MB de tamaño:

Almacena de forma eficiente centos de millóns de ficheiros pequenos. Solución autoaloxada

A diferenza de tempo entre a lectura de ficheiros é de 5 a 25 ms. Coa gravación, as cousas van peor, a diferenza é duns 150 ms. Pero neste caso non é necesario cargar ficheiros grandes; simplemente non ten sentido facelo, poden vivir separados dos arquivos.

*Tecnicamente, pode usar este servidor para tarefas que requiran NoSQL.

Métodos básicos de traballo co servidor wZD:

Cargando un ficheiro normal:

curl -X PUT --data-binary @test.jpg http://localhost/test/test.jpg

Carga dun ficheiro ao arquivo Bolt (se non se supera o parámetro de servidor fmaxsize, que determina o tamaño máximo do ficheiro que se pode incluír no arquivo; se se supera, o ficheiro cargarase como é habitual xunto ao arquivo):

curl -X PUT -H "Archive: 1" --data-binary @test.jpg http://localhost/test/test.jpg

Descargando un ficheiro (se hai ficheiros co mesmo nome no disco e no arquivo, ao descargar, dáselle prioridade por defecto ao ficheiro non arquivado):

curl -o test.jpg http://localhost/test/test.jpg

Descargando un ficheiro do arquivo Bolt (forzado):

curl -o test.jpg -H "FromArchive: 1" http://localhost/test/test.jpg

As descricións doutros métodos están na documentación.

Documentación wZD
Documentación wZA

Actualmente, o servidor só admite o protocolo HTTP; aínda non funciona con HTTPS. O método POST tampouco é compatible (aínda non se decidiu se é necesario ou non).

Quen busca no código fonte atopará alí caramelo de manteiga, non lle gusta a todos, pero eu non vinculei o código principal ás funcións do marco web, agás o manejador de interrupcións, polo que no futuro podo reescribilo rapidamente para case calquera. motor.

Facer:

  • Desenvolvemento do teu propio replicador e distribuidor + xeo para a posibilidade de uso en grandes sistemas sen sistemas de ficheiros cluster (Todo para adultos)
  • Posibilidade de recuperación inversa completa dos metadatos se se perden por completo (se utiliza un distribuidor)
  • Protocolo nativo para a capacidade de usar conexións de rede persistentes e controladores para diferentes linguaxes de programación
  • Posibilidades avanzadas para usar o compoñente NoSQL
  • Compresións de diferentes tipos (gzip, zstd, snappy) para ficheiros ou valores dentro de arquivos Bolt e para ficheiros normais
  • Cifrado de diferentes tipos para ficheiros ou valores dentro de arquivos Bolt e para ficheiros normais
  • Conversión de vídeo atrasada no servidor, incluída na GPU

Teño de todo, espero que este servidor lle sexa útil a alguén, licenza BSD-3, dobre copyright, xa que se non houbese empresa onde eu traballe, o servidor non estaría escrito. Son o único programador. Agradeceríache calquera erro e solicitude de funcións que atopes.

Fonte: www.habr.com

Engadir un comentario