Le nombre de fichiers que je conserve dans un seul répertoire est-il important? Si tel est le cas, combien de fichiers dans un répertoire sont trop nombreux et quels sont les effets d'un trop grand nombre de fichiers? (Ceci est sur un serveur Linux.)
Arrière-plan: j'ai un site Web d'album photo et chaque image téléchargée est renommée en un identifiant à 8 chiffres hexadécimaux (par exemple, a58f375c.jpg). Ceci permet d'éviter les conflits de noms de fichiers (par exemple, si de nombreux fichiers "IMG0001.JPG" sont téléchargés). Le nom de fichier d'origine et toutes les métadonnées utiles sont stockés dans une base de données. À l'heure actuelle, j'ai environ 1500 fichiers dans le répertoire images. Cela rend la liste des fichiers dans le répertoire (via FTP ou client SSH) prend quelques secondes. Mais je ne vois pas que cela ait un autre effet que celui-là. En particulier, il ne semble pas y avoir d’impact sur la rapidité avec laquelle un fichier image est servi à l’utilisateur.
J'ai envisagé de réduire le nombre d'images en créant 16 sous-répertoires: 0-9 et a-f. Ensuite, je déplaçais les images dans les sous-répertoires en fonction du premier chiffre hexadécimal du nom de fichier. Mais je ne suis pas sûr qu'il y ait une raison de le faire, à l'exception de la liste occasionnelle du répertoire via FTP/SSH.
J'ai eu plus de 8 millions de fichiers dans un seul répertoire ext3. libc readdir()
qui est utilisé par find
, ls
et la plupart des autres méthodes décrites dans ce fil de discussion pour répertorier les grands répertoires.
La raison pour laquelle ls
et find
sont lents dans ce cas est que readdir()
ne lit que 32K d'entrées de répertoire à la fois. Par conséquent, sur les disques lents, il faudra beaucoup de lectures pour répertorier un répertoire. Il y a une solution à ce problème de vitesse. J'ai écrit un article assez détaillé à ce sujet sur: http://www.olark.com/spw/2011/08/you-can-list-a-directory-with-8-million-files-but-not- avec-ls/
La clé à retenir est: utilisez directement getdents()
- http://www.kernel.org/doc/man-pages/online/pages/man2/getdents.2.html plutôt que tout ce qui est basé sur libc readdir()
vous pouvez donc spécifier la taille de la mémoire tampon lors de la lecture des entrées de répertoire à partir du disque.
Cela dépend un peu du système de fichiers spécifique utilisé sur le serveur Linux. De nos jours, le paramètre par défaut est ext3 avec dir_index, ce qui accélère la recherche de grands répertoires.
La vitesse ne devrait donc pas être un problème, autre que celui que vous avez déjà noté, à savoir que les inscriptions prendront plus longtemps.
Il y a une limite au nombre total de fichiers dans un répertoire. Je crois me souvenir que cela a fonctionné jusqu’à 32 000 fichiers.
J'ai un répertoire avec 88 914 fichiers. Comme vous, cela est utilisé pour stocker les vignettes et sur un serveur Linux.
Les fichiers listés via FTP ou une fonction php sont lents, mais l'affichage du fichier a également un impact négatif sur les performances. par exemple. www.website.com/thumbdir/gh3hg4h2b4h234b3h2.jpg a un temps d’attente de 200 à 400 ms. A titre de comparaison, sur un autre site, avec environ 100 fichiers dans un répertoire, l’image s’affiche après environ 40 ms d’attente.
J'ai donné cette réponse, car la plupart des gens viennent d'écrire le fonctionnement des fonctions de recherche dans les répertoires; vous ne l'utiliserez pas dans un dossier miniature. Il vous suffit d'afficher des fichiers de manière statique, mais vous souhaitez savoir comment les fichiers peuvent être utilisés .
Gardez à l'esprit que sous Linux, si vous avez un répertoire avec trop de fichiers, le shell risque de ne pas pouvoir développer les caractères génériques. J'ai ce problème avec un album photo hébergé sur Linux. Il stocke toutes les images redimensionnées dans un seul répertoire. Alors que le système de fichiers peut gérer de nombreux fichiers, le shell ne le peut pas. Exemple:
-Shell-3.00$ ls A*
-Shell: /bin/ls: Argument list too long
ou
-Shell-3.00$ chmod 644 *jpg
-Shell: /bin/chmod: Argument list too long
Je travaille sur un problème similaire en ce moment. Nous avons une structure de répertoire hiérarchique et utilisons des identifiants d’image comme noms de fichier. Par exemple, une image avec id=1234567
est placée dans
..../45/67/1234567_<...>.jpg
en utilisant les 4 derniers chiffres pour déterminer où le fichier va.
Avec quelques milliers d'images, vous pouvez utiliser une hiérarchie à un niveau. Notre administrateur système n'a suggéré que quelques milliers de fichiers dans un répertoire donné (ext3) pour des raisons d'efficacité/de sauvegarde/pour toute autre raison qu'il avait en tête.
Pour ce que cela vaut, je viens de créer un répertoire sur un système de fichiers ext4
contenant 1 000 000 fichiers, puis d'accéder de manière aléatoire à ces fichiers via un serveur Web. Je n'ai pas remarqué de prime sur l'accès à ceux sur (disons) seulement avoir 10 fichiers là-bas.
C’est radicalement différent de mon expérience en ce qui concerne ntfs
il ya quelques années.
Le plus gros problème que j'ai rencontré concerne un système 32 bits. Une fois que vous avez dépassé un certain nombre, des outils comme «ls» cessent de fonctionner.
Essayer de faire quelque chose avec ce répertoire une fois que vous avez passé cette barrière devient un énorme problème.
Cela dépend absolument du système de fichiers. De nombreux systèmes de fichiers modernes utilisent des structures de données correctes pour stocker le contenu des répertoires, mais les systèmes de fichiers plus anciens ajoutaient souvent les entrées à une liste. La récupération d'un fichier était donc une opération O(n).
Même si le système de fichiers fonctionne correctement, il est tout à fait possible que les programmes qui répertorient le contenu des répertoires fassent des bousilles et fassent un tri O (n ^ 2). répertoire à pas plus de 500.
Cela dépend vraiment du système de fichiers utilisé, ainsi que de certains indicateurs.
Par exemple, ext3 peut avoir plusieurs milliers de fichiers. mais après quelques milliers, il était très lent. Principalement lors de la création d'un répertoire, mais également lors de l'ouverture d'un seul fichier. Il y a quelques années, l'option "htree" avait été choisie, ce qui réduisait considérablement le temps nécessaire pour obtenir un inode à partir d'un nom de fichier.
Personnellement, j'utilise des sous-répertoires pour conserver la plupart des niveaux sous un millier d'éléments. Dans votre cas, je créerais 256 répertoires, avec les deux derniers chiffres hexadécimaux de l’ID. Utilisez les derniers chiffres et non les premiers chiffres pour équilibrer la charge.
Si le temps nécessaire à la mise en œuvre d'un schéma de partitionnement d'annuaire est minime, je suis pour. La première fois que vous devez déboguer un problème impliquant la manipulation d’un répertoire de 10000 fichiers via la console, vous comprendrez.
Par exemple, F-Spot stocke les fichiers photo au format AAAA\MM\DD\nomfichier.ext, ce qui signifie que le plus grand répertoire que j'ai eu à traiter lors de la manipulation manuelle de ma collection de ~ 20000 photos comptait environ 800 fichiers. Cela facilite également la navigation dans les fichiers à partir d’une application tierce. Ne présumez jamais que votre logiciel est la seule chose qui accédera aux fichiers de votre logiciel.
en fait, ext3 a une limite de taille de répertoire et dépend de la taille de bloc du système de fichiers. Il n'y a pas de "nombre maximal" de fichiers par répertoire, mais un "nombre maximal de blocs par répertoire utilisés pour stocker les entrées de fichier". Plus précisément, la taille du répertoire lui-même ne peut pas dépasser un arbre binaire de hauteur 3 et son déploiement dépend de la taille du bloc. Voir ce lien pour quelques détails.
https://www.mail-archive.com/[email protected]/msg01944.html
Cela m’a récemment mordu dans un système de fichiers formaté avec des blocs de 2K, qui recevait inexplicablement des messages du noyau contenant un répertoire complet warning: ext3_dx_add_entry: Directory index full!
lorsque je copiais depuis un autre système de fichiers ext3. Dans mon cas, un répertoire contenant seulement 480 000 fichiers n'a pas pu être copié vers la destination.
La question se résume à ce que vous allez faire avec les fichiers.
Sous Windows, tous les répertoires contenant plus de 2k fichiers ont tendance à s'ouvrir lentement dans Explorer. S'ils sont tous des fichiers image, plus de 1k ont tendance à s'ouvrir très lentement en mode vignette.
À une époque, la limite imposée par le système était de 32 767. C'est plus élevé maintenant, mais même cela est beaucoup trop de fichiers à gérer en même temps dans la plupart des circonstances.
Je me souviens d'avoir exécuté un programme qui créait une quantité énorme de fichiers à la sortie. Les fichiers ont été triés à 30000 par répertoire. Je ne me souviens pas d'avoir eu de problèmes de lecture lorsque j'ai dû réutiliser la sortie produite. C'était sur un ordinateur portable Ubuntu Linux 32 bits, et même Nautilus affichait le contenu du répertoire, bien qu'après quelques secondes.
système de fichiers ext3: Un code similaire sur un système 64 bits traitait bien 64 000 fichiers par répertoire.
J'ai rencontré un problème similaire. J'essayais d'accéder à un répertoire contenant plus de 10 000 fichiers. Il a fallu trop de temps pour créer la liste de fichiers et exécuter tout type de commande sur l’un des fichiers.
J'ai imaginé un petit script php pour le faire moi-même et j'ai essayé de trouver un moyen de l'empêcher de passer à travers le navigateur.
Ce qui suit est le script php que j'ai écrit pour résoudre le problème.
Liste des fichiers d'un répertoire contenant trop de fichiers pour FTP
Comment ça aide quelqu'un
Je préfère la même manière que @armandino . Pour cela, j'utilise cette petite fonction dans PHP pour convertir les identifiants en un chemin de fichier donnant 1000 fichiers par répertoire:
function dynamic_path($int) {
// 1000 = 1000 files per dir
// 10000 = 10000 files per dir
// 2 = 100 dirs per dir
// 3 = 1000 dirs per dir
return implode('/', str_split(intval($int / 1000), 2)) . '/';
}
ou vous pouvez utiliser la deuxième version si vous souhaitez utiliser un format alphanumérique:
function dynamic_path2($str) {
// 26 alpha + 10 num + 3 special chars (._-) = 39 combinations
// -1 = 39^2 = 1521 files per dir
// -2 = 39^3 = 59319 files per dir (if every combination exists)
$left = substr($str, 0, -1);
return implode('/', str_split($left ? $left : $str[0], 2)) . '/';
}
résultats:
<?php
$files = explode(',', '1.jpg,12.jpg,123.jpg,999.jpg,1000.jpg,1234.jpg,1999.jpg,2000.jpg,12345.jpg,123456.jpg,1234567.jpg,12345678.jpg,123456789.jpg');
foreach ($files as $file) {
echo dynamic_path(basename($file, '.jpg')) . $file . PHP_EOL;
}
?>
1/1.jpg
1/12.jpg
1/123.jpg
1/999.jpg
1/1000.jpg
2/1234.jpg
2/1999.jpg
2/2000.jpg
13/12345.jpg
12/4/123456.jpg
12/35/1234567.jpg
12/34/6/12345678.jpg
12/34/57/123456789.jpg
<?php
$files = array_merge($files, explode(',', 'a.jpg,b.jpg,ab.jpg,abc.jpg,ddd.jpg,af_ff.jpg,abcd.jpg,akkk.jpg,bf.ff.jpg,abc-de.jpg,abcdef.jpg,abcdefg.jpg,abcdefgh.jpg,abcdefghi.jpg'));
foreach ($files as $file) {
echo dynamic_path2(basename($file, '.jpg')) . $file . PHP_EOL;
}
?>
1/1.jpg
1/12.jpg
12/123.jpg
99/999.jpg
10/0/1000.jpg
12/3/1234.jpg
19/9/1999.jpg
20/0/2000.jpg
12/34/12345.jpg
12/34/5/123456.jpg
12/34/56/1234567.jpg
12/34/56/7/12345678.jpg
12/34/56/78/123456789.jpg
a/a.jpg
b/b.jpg
a/ab.jpg
ab/abc.jpg
dd/ddd.jpg
af/_f/af_ff.jpg
ab/c/abcd.jpg
ak/k/akkk.jpg
bf/.f/bf.ff.jpg
ab/c-/d/abc-de.jpg
ab/cd/e/abcdef.jpg
ab/cd/ef/abcdefg.jpg
ab/cd/ef/g/abcdefgh.jpg
ab/cd/ef/gh/abcdefghi.jpg
Comme vous pouvez le constater pour la version $int
-, chaque dossier contient jusqu'à 1 000 fichiers et jusqu'à 99 répertoires contenant 1 000 fichiers et 99 répertoires ...
Mais n'oubliez pas que beaucoup de répertoires peuvent accélérer votre processus de sauvegarde. N'hésitez pas à tester 1000 à 10000 fichiers par répertoire, mais n'en ajoutez pas davantage car vous aurez de très longs temps d'accès si vous souhaitez lire le répertoire fichier par fichier (clients ftp, fonctions de lecture de fichiers, etc.).
Enfin, vous devriez réfléchir à la manière de réduire le nombre total de fichiers. En fonction de votre cible, vous pouvez utiliser des images-objets CSS pour combiner plusieurs minuscules images telles que des avatars, des icônes, des smileys, etc. au format JSON. Dans mon cas, j’avais des milliers de mini-caches et j’ai finalement décidé de les combiner par paquets de 10.
Je respecte cela, mais je ne réponds pas totalement à votre question de savoir combien est trop, mais une idée pour résoudre le problème à long terme est qu’en plus du stockage des métadonnées du fichier original, stockez également le dossier sur lequel il est stocké - normaliser sur ce morceau de métadonnées. Une fois qu'un dossier dépasse les limites avec lesquelles vous êtes à l'aise pour des raisons de performances, d'esthétique ou pour une raison quelconque, vous créez simplement un deuxième dossier et commencez à y déposer des fichiers ...
Ce que la plupart des réponses ci-dessus ne montrent pas, c'est qu'il n'y a pas de réponse unique à la question initiale.
Dans l'environnement actuel, nous avons un grand conglomérat de matériel et de logiciels différents - certains sont en 32 bits, d'autres en 64 bits, d'autres sont très sophistiqués, d'autres sont éprouvés - fiables et ne changent jamais . des matériels plus anciens et plus récents, des systèmes d’exploitation plus anciens et plus récents, différents fournisseurs (Windows, Unix, Apple, etc.) et une myriade d’utilitaires et de serveurs qui vont de pair. Le matériel s’est amélioré et le logiciel converti en compatibilité 64 bits, il a nécessairement fallu beaucoup de temps pour que toutes les pièces de ce monde très vaste et complexe puissent bien jouer avec le rythme rapide des changements.
IMHO il n'y a pas qu'un seul moyen de résoudre un problème. La solution consiste à rechercher les possibilités et ensuite, par essais et erreurs, à trouver ce qui convient le mieux à vos besoins particuliers. Chaque utilisateur doit déterminer ce qui fonctionne pour son système plutôt que d'utiliser une approche à l'emporte-pièce.
J'ai par exemple un serveur multimédia avec quelques fichiers très volumineux. Le résultat est seulement environ 400 fichiers remplissant un lecteur 3 TB. Seulement 1% des inodes sont utilisés, mais 95% de l'espace total est utilisé. Une autre personne, avec beaucoup de fichiers plus petits, risque de manquer d’inodes avant de remplir l’espace. (Sur les systèmes de fichiers ext4 en règle générale, un inode est utilisé pour chaque fichier/répertoire.) Alors que, théoriquement, le nombre total de fichiers pouvant être contenus dans un répertoire est presque infini, l'aspect pratique en détermine que l'utilisation globale est réaliste. unités, pas seulement les capacités du système de fichiers.
J'espère que toutes les réponses ci-dessus ont favorisé la réflexion et la résolution de problèmes plutôt que de constituer un obstacle insurmontable au progrès.
J'ai eu le même problème. Essayer de stocker des millions de fichiers sur un serveur Ubuntu dans ext4. Terminé l'exécution de mes propres points de repère. Vous avez découvert que le répertoire à plat fonctionnait mieux tout en étant plus simple à utiliser:
A écrit un article .
Il n’existe pas de chiffre "trop", pour autant qu’il ne dépasse pas les limites du système d’exploitation. Cependant, plus le nombre de fichiers contenus dans un répertoire, quel que soit le système d'exploitation, plus il faut de temps pour accéder à un fichier individuel et, sur la plupart des systèmes d'exploitation, les performances sont non linéaires. puis trouver un fichier sur 1 000.
Les problèmes secondaires associés à la présence de nombreux fichiers dans un répertoire incluent des échecs d'extension de caractères génériques. Pour réduire les risques, vous pouvez envisager de classer vos répertoires par date de téléchargement ou par tout autre élément de métadonnée utile.
Pas une réponse, mais juste quelques suggestions.
Sélectionnez un fichier plus approprié FS (système de fichiers). D'un point de vue historique, tous vos problèmes étaient suffisamment judicieux pour être une fois au cœur de l'évolution des SF au fil des décennies. Je veux dire plus moderne FS mieux soutenir vos problèmes. Commencez par créer une table de décision de comparaison basée sur votre objectif ultime, à partir de FS list .
Je pense qu'il est temps de changer vos paradigmes. Je suggère donc personnellement d’utiliser un système distribué FS , ce qui signifie qu’il n’ya aucune limite en ce qui concerne la taille, le nombre de fichiers, etc.
Je ne suis pas sûr de pouvoir travailler, mais si vous ne parlez pas d'expérimentation, essayez AUFS avec votre système de fichiers actuel. J'imagine qu'il est doté d'installations permettant d'imiter plusieurs dossiers sous la forme d'un seul dossier virtuel.
Pour dépasser les limites matérielles, vous pouvez utiliser RAID-0.