Stockage efficace de centaines de millions de petits fichiers. Solution auto-hébergée



Chère communauté, cet article se concentrera sur le stockage et la livraison efficaces de centaines de millions de petits fichiers. À ce stade, la solution finale pour les systèmes de fichiers compatibles POSIX avec prise en charge complète des verrous, y compris ceux en cluster, et même sans béquilles, est proposée.

C'est pourquoi j'ai écrit à cet effet mon propre serveur spécialisé.
Au cours de cette tâche, il a été possible de résoudre le problème principal, tout en économisant de l'espace disque et de la RAM, que notre système de fichiers de cluster a impitoyablement consommé. En fait, un tel nombre de fichiers est nuisible à tout système de fichiers en cluster.

L'idée est la suivante:

En termes simples, les petits fichiers sont téléchargés via le serveur, ils sont enregistrés directement dans l'archive et sont également lus à partir de celui-ci, et les gros fichiers sont placés à proximité. Schéma: 1 dossier = 1 archive, au total nous avons plusieurs millions d'archives avec de petits fichiers, et non plusieurs centaines de millions de fichiers. Et tout cela est entièrement implémenté, sans aucun script ni pliage de fichiers dans des archives tar / zip.

Je vais essayer de le raccourcir, je m'excuse à l'avance si le message sera volumineux.

Tout a commencé avec le fait que je ne pouvais pas trouver un serveur approprié dans le monde qui pourrait enregistrer les données reçues via le protocole HTTP directement dans les archives, de sorte qu'il n'y avait pas d'inconvénients inhérents aux archives ordinaires et aux référentiels d'objets. Et la raison de la recherche était un cluster de 10 serveurs qui est devenu une origine à grande échelle, dans laquelle 250 000 000 de petits fichiers s'étaient déjà accumulés, et la tendance à la croissance n'allait pas s'arrêter.

Ceux qui n'aiment pas lire les articles et un peu de documentation sont plus faciles:

ici et ici .

Mettre à jour Suppression de nginx de l'image docker.

Et docker en même temps:
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 

Suivant:

Mettre à jour Dans la version 1.1.0, la méthode d'authentification HTTPS / POST / IP, etc., est déjà apparue.

S'il y a beaucoup de fichiers, des ressources importantes sont nécessaires et, plus offensivement, certains d'entre eux sont gaspillés. Par exemple, lorsque vous utilisez un système de fichiers en cluster (dans ce cas, MooseFS), un fichier, quelle que soit sa taille réelle, prend toujours au moins 64 Ko. Autrement dit, pour les fichiers de 3, 10 ou 30 Ko, 64 Ko sont requis sur le disque. Si un quart de milliard de fichiers, on perd de 2 à 10 téraoctets. Il ne sera pas possible de créer de nouveaux fichiers à l'infini car il y a une limitation dans MooseFS lui-même: pas plus d'un milliard avec une réplique de chaque fichier.

À mesure que le nombre de fichiers augmente, vous avez besoin de beaucoup de RAM pour les métadonnées. Les décharges de métadonnées fréquentes et importantes contribuent également à l'usure des disques SSD.

Serveur WZD. Nous mettons les disques en ordre.

Le serveur est écrit en Go. Tout d'abord, je devais réduire le nombre de fichiers. Comment faire En raison de l'archivage, mais dans ce cas sans compression, car mes fichiers sont des images solides et écrêtées. BoltDB est venu à la rescousse, qui devait encore être privé de défauts, cela se reflète dans la documentation.

Au total, au lieu d'un quart de milliard de fichiers, dans mon cas, il ne reste que 10 millions d'archives Bolt. Si j'avais l'occasion de changer la structure actuelle de remplissage des fichiers de répertoire, il serait alors possible de réduire à environ 1 million de fichiers.

Tous les petits fichiers sont emballés dans les archives Bolt, recevant automatiquement les noms des répertoires dans lesquels ils se trouvent, et tous les gros fichiers restent côte à côte avec les archives, cela n'a aucun sens de les emballer, cela est personnalisable. Petit - archive, grand - laissez inchangé. Le serveur fonctionne de manière transparente avec les deux.

Architecture et fonctionnalités du serveur wZD.



Le serveur exécute Linux, BSD, Solaris et OSX. J'ai testé uniquement l'architecture AMD64 sous Linux, mais elle devrait également convenir pour ARM64, PPC64, MIPS64.

Caractéristiques clés:

  • Multithreading;
  • Multi-serveur, offrant une tolérance aux pannes et un équilibrage de charge;
  • Transparence maximale pour l'utilisateur ou le développeur;
  • Méthodes HTTP prises en charge: GET, HEAD, PUT et DELETE;
  • Gestion des comportements de lecture et d'écriture via les en-têtes clients;
  • Prise en charge d'hôtes virtuels personnalisables;
  • Prend en charge l'intégrité des données CRC lors de l'écriture / lecture;
  • Tampons semi-dynamiques pour une consommation de mémoire minimale et un réglage optimal des performances du réseau;
  • Compaction de données retardée
  • De plus, un archiveur wZA multithread est proposé pour la migration de fichiers sans arrêter le service.

Expérience réelle:

J'ai développé et testé le serveur et l'archiveur sur des données en direct pendant assez longtemps, maintenant il fonctionne avec succès sur un cluster qui comprend 250 000 000 de petits fichiers (images) situés dans 15 000 000 répertoires sur des disques SATA séparés. Un cluster de 10 serveurs est un serveur Origin installé derrière un réseau CDN. Pour sa maintenance, 2 serveurs Nginx + 2 serveurs wZD sont utilisés.

Pour ceux qui décident d'utiliser ce serveur, il est judicieux de planifier la structure du répertoire avant utilisation, le cas échéant. Réservez immédiatement que le serveur n'est pas conçu pour tout pousser dans l'archive 1 Bolt.

Test de performance:

Plus la taille du fichier archivé est petite, plus les opérations GET et PUT sont rapides sur celui-ci. Comparez le temps total pendant lequel le client HTTP écrit dans des fichiers normaux et dans des archives Bolt, et lit également. Il compare le travail avec des fichiers de taille 32 Ko, 256 Ko, 1024 Ko, 4096 Ko et 32 ​​768 Ko.

Lorsque vous travaillez avec des archives Bolt, l'intégrité des données de chaque fichier est vérifiée (CRC est utilisé), avant l'écriture et également après l'écriture, la lecture est effectuée à la volée et le recomptage, cela introduit naturellement des retards, mais l'essentiel est la sécurité des données.

J'ai effectué des tests de performances sur les SSD, car sur les disques SATA, les tests ne montrent pas de différence claire.

Mise à jour (v1.1.0), amélioration des performances de 5 à 25%.

Graphiques basés sur les résultats des tests:




Comme vous pouvez le voir, pour les petits fichiers, la différence de temps de lecture et d'écriture entre les fichiers archivés et non archivés est faible.

Nous obtiendrons une image complètement différente avec le test de lecture et d'écriture de fichiers de 32 Mo:



La différence de temps entre la lecture des fichiers est de 5 à 25 ms. Avec l'enregistrement, les choses sont pires, la différence est d'environ 150 ms. Mais dans ce cas, il n'est pas nécessaire de télécharger de gros fichiers, cela n'a tout simplement pas de sens, ils peuvent vivre séparément des archives.

* Techniquement, ce serveur peut également être utilisé pour des tâches nécessitant NoSQL.

Méthodes de base pour travailler avec le serveur wZD:

Téléchargez le fichier régulier:
 curl -X PUT --data-binary @test.jpg http://localhost/test/test.jpg 

Téléchargement d'un fichier dans l'archive Bolt (si le paramètre serveur fmaxsize n'est pas dépassé, ce qui détermine la taille de fichier maximale pouvant être incluse dans l'archive, s'il est dépassé, le fichier sera chargé comme d'habitude à côté de l'archive):
 curl -X PUT -H "Archive: 1" --data-binary @test.jpg http://localhost/test/test.jpg 

Téléchargement d'un fichier (s'il y a des fichiers du même nom sur le disque et dans l'archive, alors lors du téléchargement, la priorité par défaut est donnée au fichier décompressé):
 curl -o test.jpg http://localhost/test/test.jpg 

Téléchargement d'un fichier à partir de l'archive Bolt (forcé):
 curl -o test.jpg -H "FromArchive: 1" http://localhost/test/test.jpg 


Une description des autres méthodes se trouve dans la documentation.

Documentation WZD
Documentation WZA

Jusqu'à présent, le serveur ne prend en charge que HTTP, il ne fonctionne pas encore avec HTTPS. La méthode POST n'est pas non plus prise en charge (il n'a pas encore été décidé si elle est nécessaire ou non).

Quiconque plonge dans le code source y trouvera un caramel, tout le monde ne l'aime pas, mais je n'ai pas lié le code principal aux fonctions du framework Web, à l'exception du gestionnaire d'interruption, de sorte qu'à l'avenir je puisse réécrire rapidement sur presque n'importe quel moteur.

À faire:

  • Développement de notre propre réplicateur et distributeur + géo pour la possibilité d'utilisation dans de grands systèmes sans cluster FS (Tout pour un adulte)
  • La possibilité d'inverser complètement les métadonnées de restauration lorsqu'elles sont complètement perdues (si vous utilisez un distributeur)
  • Protocole natif pour la possibilité d'utiliser des connexions réseau permanentes et des pilotes pour différents langages de programmation
  • Fonctionnalités avancées de l'utilisation du composant NoSQL
  • Compressions de différents types (gzip, zstd, snappy) pour les fichiers ou les valeurs dans les archives Bolt et pour les fichiers ordinaires
  • Cryptage de différents types de fichiers ou de valeurs dans les archives Bolt et pour les fichiers ordinaires
  • Conversion vidéo de serveur retardée, y compris GPU

C'est tout, j'espère que ce serveur sera utile pour quelqu'un, licence BSD-3, double copyright, car il n'y aurait pas d'entreprise où je travaille, je n'écrirais pas non plus de serveur. Je suis développeur au singulier. Je serais reconnaissant pour les bogues trouvés et les demandes de fonctionnalités.

Source: https://habr.com/ru/post/fr484312/


All Articles