Stockez efficacement des centaines de millions de petits fichiers. Solution auto-hébergée

Stockez efficacement des centaines de millions de petits fichiers. Solution auto-hébergée

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

J'ai donc écrit mon propre serveur personnalisé à cet effet.
Au cours de la mise en œuvre de cette tâche, nous avons réussi à 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 consommait sans pitié. En fait, un tel nombre de fichiers est dangereux pour 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 également lus à partir de celle-ci, et les gros fichiers sont placés côte à côte. 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 placement de fichiers dans des archives tar/zip.

Je vais essayer d'être bref, je m'excuse d'avance si le message est long.

Tout a commencé avec le fait que je ne trouvais pas de serveur approprié au monde capable de sauvegarder les données reçues via le protocole HTTP directement dans les archives, sans les inconvénients inhérents aux archives conventionnelles et au stockage d'objets. Et la raison de la recherche était le cluster Origin de 10 serveurs qui s'était développé à grande échelle, dans lequel 250,000,000 XNUMX XNUMX de petits fichiers s'étaient déjà accumulés, et la tendance à la croissance n'allait pas s'arrêter.

Pour ceux qui n’aiment pas lire des articles, un peu de documentation est plus simple :

ici и ici.

Et docker en même temps, il y a maintenant une option uniquement avec nginx à l'intérieur juste au cas où :

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

Suivant:

S’il y a beaucoup de fichiers, des ressources importantes sont nécessaires, et le pire est que certaines d’entre elles sont gaspillées. Par exemple, lors de l'utilisation d'un système de fichiers en cluster (dans ce cas, MooseFS), le fichier, quelle que soit sa taille réelle, occupe toujours au moins 64 Ko. Autrement dit, pour les fichiers de 3, 10 ou 30 Ko, 64 Ko sont requis sur le disque. S'il y a un quart de milliard de fichiers, nous perdons de 2 à 10 téraoctets. Il ne sera pas possible de créer de nouveaux fichiers indéfiniment, puisque MooseFS a une limitation : pas plus d'un milliard avec une réplique de chaque fichier.

À mesure que le nombre de fichiers augmente, une grande quantité de RAM est nécessaire pour les métadonnées. Les vidages fréquents et volumineux de métadonnées contribuent également à l’usure des disques SSD.

Serveur wZD. Nous mettons les choses en ordre sur les disques.

Le serveur est écrit en Go. Tout d’abord, je devais réduire le nombre de fichiers. Comment faire? Grâce à l'archivage, mais dans ce cas sans compression, puisque mes fichiers ne sont que des images compressées. BoltDB est venu à la rescousse, qui devait encore être éliminé de ses défauts, cela se reflète dans la documentation.

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

Tous les petits fichiers sont regroupés dans des archives Bolt, qui reçoivent automatiquement les noms des répertoires dans lesquels ils se trouvent, et tous les gros fichiers restent à côté des archives ; cela ne sert à rien de les compresser, c'est personnalisable. Les petits sont archivés, les grands restent inchangés. Le serveur fonctionne de manière transparente avec les deux.

Architecture et fonctionnalités du serveur wZD.

Stockez efficacement des centaines de millions de petits fichiers. Solution auto-hébergée

Le serveur fonctionne sous les systèmes d'exploitation Linux, BSD, Solaris et OSX. J'ai testé uniquement l'architecture AMD64 sous Linux, mais cela devrait fonctionner pour ARM64, PPC64, MIPS64.

Caractéristiques principales:

  • Multithreading ;
  • Multiserveur, 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 ;
  • Contrôle du comportement de lecture et d'écriture via les en-têtes clients ;
  • Prise en charge des hôtes virtuels flexibles ;
  • 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 ;
  • Compactage des données différé ;
  • De plus, un archiveur multithread wZA est proposé pour migrer des fichiers sans arrêter le service.

Expérience réelle :

Je développe et teste le serveur et l'archiveur sur des données en direct depuis assez longtemps. Il fonctionne désormais avec succès sur un cluster qui comprend 250,000,000 15,000,000 10 de petits fichiers (images) situés dans 2 2 XNUMX de répertoires sur des disques SATA séparés. Un cluster de XNUMX serveurs est un serveur Origin installé derrière un réseau CDN. Pour le desservir, XNUMX serveurs Nginx + XNUMX serveurs wZD sont utilisés.

Pour ceux qui décident d'utiliser ce serveur, il serait sage de planifier la structure des répertoires, le cas échéant, avant utilisation. Permettez-moi de faire une réserve tout de suite sur le fait que le serveur n'est pas destiné à tout entasser dans une archive 1 Bolt.

Test de performance:

Plus la taille du fichier compressé est petite, plus les opérations GET et PUT sont effectuées rapidement. Comparons le temps total d'écriture du client HTTP avec les fichiers normaux et les archives Bolt, ainsi que la lecture. Le travail avec des fichiers de tailles 32 Ko, 256 Ko, 1024 4096 Ko, 32768 XNUMX Ko et XNUMX ​​XNUMX Ko est comparé.

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

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

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

Stockez efficacement des centaines de millions de petits fichiers. Solution auto-hébergée
Stockez efficacement des centaines de millions de petits fichiers. Solution auto-hébergée

Comme vous pouvez le constater, 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 obtenons une image complètement différente lors des tests de lecture et d'écriture de fichiers d'une taille de 32 Mo :

Stockez efficacement des centaines de millions de petits fichiers. Solution auto-hébergée

La différence de temps entre la lecture des fichiers est comprise entre 5 et 25 ms. Avec l'enregistrement, c'est pire, la différence est d'environ 150 ms. Mais dans ce cas, il n'est pas nécessaire de télécharger des fichiers volumineux ; cela ne sert tout simplement à rien ; ils peuvent vivre séparément des archives.

*Techniquement, vous pouvez utiliser ce serveur pour des tâches nécessitant NoSQL.

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

Chargement d'un fichier normal :

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 du serveur fmaxsize, qui détermine la taille maximale du fichier pouvant être inclus dans l'archive, n'est pas dépassé ; s'il est dépassé, le fichier sera télé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é est donnée par défaut au fichier non archivé) :

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

Téléchargement d'un fichier depuis l'archive Bolt (forcé) :

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

Les descriptions d'autres méthodes se trouvent dans la documentation.

Documentation wZD
Documentation wZA

Le serveur ne prend actuellement en charge que le protocole 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 fouille dans le code source y trouvera du caramel au beurre, 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, donc à l'avenir je pourrai le réécrire rapidement pour presque n'importe quel moteur.

ToDo:

  • Développement de votre propre réplicateur et distributeur + géo pour la possibilité d'une utilisation dans de grands systèmes sans systèmes de fichiers en cluster (Tout pour les adultes)
  • Possibilité de récupération inversée complète des métadonnées en cas de perte totale (si utilisation d'un distributeur)
  • Protocole natif pour la possibilité d'utiliser des connexions réseau persistantes et des pilotes pour différents langages de programmation
  • Possibilités avancées d'utilisation du composant NoSQL
  • Compressions de différents types (gzip, zstd, snappy) pour les fichiers ou valeurs dans les archives Bolt et pour les fichiers normaux
  • Cryptage de différents types pour les fichiers ou les valeurs dans les archives Bolt et pour les fichiers normaux
  • Conversion vidéo retardée côté serveur, y compris sur GPU

J'ai tout, j'espère que ce serveur sera utile à quelqu'un, licence BSD-3, double copyright, car s'il n'y avait pas d'entreprise où je travaille, le serveur n'aurait pas été écrit. Je suis le seul développeur. Je serais reconnaissant pour tous les bugs et demandes de fonctionnalités que vous trouverez.

Source: habr.com

Ajouter un commentaire