Quelles sont les implications en termes de performances pour des millions de fichiers dans un système de fichiers moderne?

30

Disons que nous utilisons ext4 (avec dir_index activé) pour héberger environ 3 millions de fichiers (avec une taille moyenne de 750 Ko) et que nous devons décider du schéma de dossiers que nous allons utiliser.

Dans la première solution , nous appliquons une fonction de hachage au fichier et utilisons un dossier à deux niveaux (étant 1 caractère pour le premier niveau et 2 caractères pour le deuxième niveau): étant donc le filex.forhachage égal à abcde1234 , nous le stockerons sur / path / a / bc /abcde1234-filex.for.

Dans la deuxième solution , nous appliquons une fonction de hachage au fichier et utilisons un dossier à deux niveaux (étant 2 caractères pour le premier niveau et 2 caractères pour le deuxième niveau): étant donc le filex.forhachage égal à abcde1234 , nous le stockerons sur / path / ab / de /abcde1234-filex.for.

Pour la première solution, nous aurons le schéma suivant /path/[16 folders]/[256 folders]avec une moyenne de 732 fichiers par dossier (le dernier dossier, où le fichier résidera).

Alors que sur la deuxième solution, nous aurons /path/[256 folders]/[256 folders]une moyenne de 45 fichiers par dossier .

Étant donné que nous allons beaucoup écrire / dissocier / lire des fichiers ( mais surtout lire ) à partir de ce schéma (essentiellement le système de mise en cache nginx), cela a-t-il une importance, en termes de performances, si nous choisissons l'une ou l'autre solution?

De plus, quels sont les outils que nous pourrions utiliser pour vérifier / tester cette configuration?

leandro moreira
la source
7
De toute évidence, l'analyse comparative sera utile. Mais ext4 n'est peut-être pas le bon système de fichiers pour cela. Je regarderais XFS.
ewwhite
4
Je ne regarderais pas seulement XFS, je l'utiliserais immédiatement sans plus tarder. L'arbre B + bat à chaque fois la table de hachage.
Michael Hampton
Merci pour les conseils, l'analyse comparative est un peu difficile cependant, j'ai essayé hdparm -Tt /dev/hdXmais ce n'est peut-être pas l'outil le plus approprié.
leandro moreira
2
Non, ce hdparmn'est pas le bon outil, c'est une vérification des performances brutes du périphérique de bloc et non un test du système de fichiers.
HBruijn

Réponses:

28

La raison pour laquelle on créerait ce type de structure de répertoires est que les systèmes de fichiers doivent localiser un fichier dans un répertoire, et plus le répertoire est grand, plus cette opération est lente.

Le ralentissement dépend de la conception du système de fichiers.

Le système de fichiers ext4 utilise une arborescence B pour stocker les entrées du répertoire. Une recherche sur cette table devrait prendre du temps O (log n) , la plupart du temps inférieur à la table linéaire naïve utilisée par ext3 et les systèmes de fichiers précédents (et dans le cas contraire, le répertoire est trop petit pour vraiment important).

Le système de fichiers XFS utilise à la place une arborescence B + . L'avantage de ceci sur une table de hachage ou un arbre B est que n'importe quel nœud peut avoir plusieurs enfants b , où dans XFS b varie et peut atteindre 254 (ou 19 pour le nœud racine; et ces nombres peuvent être obsolètes ). Cela vous donne une complexité temporelle de O (log b n) , une amélioration considérable.

L'un ou l'autre de ces systèmes de fichiers peut gérer des dizaines de milliers de fichiers dans un seul répertoire, XFS étant nettement plus rapide que ext4 sur un répertoire avec le même nombre d'inodes. Mais vous ne voulez probablement pas un seul répertoire avec des inodes 3M, car même avec une arborescence B +, la recherche peut prendre un certain temps. C'est ce qui a conduit à créer des répertoires de cette manière en premier lieu.

Quant à vos structures proposées, la première option que vous avez donnée est exactement ce qui est montré dans les exemples nginx. Il fonctionnera bien sur l'un ou l'autre des systèmes de fichiers, bien que XFS aura toujours un petit avantage. La deuxième option peut fonctionner légèrement mieux ou légèrement pire, mais elle sera probablement assez proche, même sur les benchmarks.

Michael Hampton
la source
Et pour XFS ou ext4, le matériel sur lequel vous mettez le système de fichiers aura un impact énorme sur les performances. Un lecteur SATA lent de 5400 tr / min peut effectuer environ 50 opérations d'E / S aléatoires / s, un bon lecteur SAS de 15 000 tr / min peut en faire quelques centaines, et un SSD sera probablement à bande passante limitée et pourrait obtenir quelques millions d'opérations d'E / S aléatoires / s sinon plus.
Andrew Henle
1
À strictement parler, $ O (\ log_b n) $ pour $ b $ fixe a la même complexité que $ O (\ log n) $. Mais pour l'OP, les constantes réelles importent.
Hagen von Eitzen du
À moins qu'il y ait un problème avec mon système de fichiers, ext4 ne peut pas gérer 10 000 fichiers dans un seul répertoire. Faire un simple ls -lprend une minute entière si le répertoire a abandonné le cache d'inode. Et quand il est mis en cache, il prend toujours plus d'une seconde. C'est avec un SSD et un Xeon avec des tonnes de RAM sur un serveur Web à faible trafic.
Abhi Beckert
@AbhiBeckert A-t-il été mis à niveau depuis ext3? Si c'est le cas, essayez de créer un nouveau répertoire et déplacez-y les fichiers.
Michael Hampton
@Hampton Non, c'est un serveur (assez) récemment installé sur du matériel moderne. Je travaille sur le problème avec notre administrateur système / centre de données depuis quelques mois. Nous payons des milliers de dollars par mois pour louer le serveur et n'obtenons pas de performances acceptables. Il semble que la seule option soit de passer à une nouvelle structure de répertoires - peut-être en utilisant des hachages au lieu de dates pour que les noms de fichiers le répartissent plus uniformément.
Abhi Beckert
5

D'après mon expérience, l'un des facteurs de mise à l'échelle est la taille des inodes compte tenu d'une stratégie de partitionnement par nom de hachage.

Les deux options proposées créent jusqu'à trois entrées d'inode pour chaque fichier créé. De plus, 732 fichiers créeront un inode qui est toujours inférieur aux 16 Ko habituels. Pour moi, cela signifie que l'une ou l'autre option fera de même.

Je vous applaudis pour votre court hachage; les systèmes précédents sur lesquels j'ai travaillé ont pris le sha1sum du fichier donné et les répertoires épissés basés sur cette chaîne, un problème beaucoup plus difficile.

sysadmin1138
la source
1
Qu'est-ce qui rend l'utilisation des sommes SHA1 (et autres sommes de hachage plus longues) "un problème beaucoup plus difficile"? C'est lourd pour les utilisateurs humains, oui, mais c'est la même chose pour le système d'exploitation, le système de fichiers et d'autres programmes.
kbolino
4

Certes, l'une ou l'autre option aidera à réduire le nombre de fichiers dans un répertoire à quelque chose qui semble raisonnable, pour xfs ou ext4 ou tout autre système de fichiers. Ce n'est pas évident, ce qui est mieux, aurait à tester pour le dire.

La comparaison avec votre application simulant quelque chose comme la charge de travail réelle est idéale. Sinon, imaginez quelque chose qui simule spécifiquement de nombreux petits fichiers. En parlant de cela, voici un open source appelé smallfile . Sa documentation fait référence à d'autres outils.

hdparmfaire des E / S soutenues n'est pas aussi utile. Il n'affichera pas les nombreuses petites E / S ou entrées de répertoire géantes associées à de très nombreux fichiers.

John Mahowald
la source
1

L'un des problèmes est la façon de numériser le dossier.

Imaginez la méthode Java qui exécute l'analyse sur le dossier.

Il devra allouer une grande quantité de mémoire et la désallouer en peu de temps, ce qui est très lourd pour la JVM.

La meilleure façon est d'organiser la structure des dossiers de la façon dont chaque fichier est dans un dossier dédié, par exemple l'année / mois / jour.

La façon dont l'analyse complète est effectuée est que pour chaque dossier, il y a une exécution de la fonction, donc JVM va quitter la fonction, désallouer la RAM et la réexécuter sur un autre dossier.

Ce n'est qu'un exemple, mais de toute façon avoir un dossier aussi énorme n'a aucun sens.

Andrew Smith
la source
2
Vous supposez Java et numérisez le dossier. Aucun n'est mentionné dans la question, et il existe d'autres façons de traiter le dossier en Java en plus de le numériser.
user207421
1

J'ai eu le même problème. Essayer de stocker des millions de fichiers sur un serveur Ubuntu en ext4. Fin de l'exécution de mes propres repères. J'ai découvert que le répertoire plat fonctionne bien mieux tout en étant plus simple à utiliser:

référence

A écrit un article .

Hartator
la source
Ce n'est certainement pas le résultat escompté. Avant de vous lancer ou de le recommander, vous devriez chercher plus profondément pourquoi vous avez obtenu ce résultat inattendu.
Michael Hampton