J'ai un site Web qui stockera des images de profil utilisateur. Chaque image est stockée dans un répertoire (Linux) spécifique à l'utilisateur. Actuellement, j'ai une base de clients de 30+, ce qui signifie que j'aurai plus de 30 dossiers. Mais ma boîte Linux actuelle (ext2 / ext3) ne prend pas en charge la création de plus de 32 000 répertoires. Comment puis-je surmonter cela? Même les gars de YouTube ont le même problème, avec les vignettes vidéo. Mais ils l'ont résolu en passant à ReiserFS. Ne pouvons-nous pas avoir une meilleure solution?
Mise à jour: Lorsqu'on leur a demandé dans IRC, les gens demandaient de le mettre à niveau vers ext4, qui a une limite de 64k et bien sûr, vous pouvez même dépasser cela aussi . Ou piratage du noyau pour changer la limite.
Mise à jour: que diriez-vous de diviser la base d'utilisateurs en dossiers en fonction de la plage d'ID utilisateur. Cela signifie 1-1000 dans un dossier, 1000-2000 dans l'autre comme ça. Cela semble simple. Que dites-vous, les gars?
Franchement, n'y a-t-il pas d'autre moyen?
la source
Réponses:
Cette limite est par répertoire, pas pour l'ensemble du système de fichiers, vous pouvez donc le contourner en subdivisant davantage les choses. Par exemple, au lieu d'avoir tous les sous-répertoires utilisateur dans le même répertoire, divisez-les par les deux premiers caractères du nom, vous avez donc quelque chose comme:
Encore mieux serait de créer une forme de hachage des noms et de l'utiliser pour la division. De cette façon, vous obtiendrez une meilleure répartition parmi les répertoires au lieu de, avec l'exemple des lettres initiales, "da" étant très plein et "zz" complètement vide. Par exemple, si vous prenez le nom CRC ou MD5 et utilisez les 8 premiers bits, vous obtiendrez quelque chose comme:
Cela peut être étendu à d'autres profondeurs selon les besoins, par exemple comme si vous n'utilisez pas le nom d'utilisateur comme valeur de hachage:
Cette méthode est utilisée dans de nombreux endroits comme le cache de Squid, pour copier l'exemple de Ludwig et les caches locaux des navigateurs Web.
Une chose importante à noter est qu'avec ext2 / 3, vous commencerez à rencontrer des problèmes de performances avant de vous approcher de la limite de 32 000, car les répertoires sont recherchés de manière linéaire. Le passage à un autre système de fichiers (ext4 ou reiser par exemple) supprimera cette inefficacité (reiser recherche les répertoires avec un algorithme divisé en binaires, de sorte que les longs répertoires sont gérés beaucoup plus efficacement, ext4 peut également le faire) ainsi que la limite fixe par répertoire.
la source
Si vous êtes lié à ext2 / ext3, la seule possibilité que je vois est de partitionner vos données. Trouvez un critère qui divise vos données en morceaux gérables de taille similaire.
Si ce n'est que sur les images de profil que je ferais:
Par exemple, le cache SQUID procède comme suit:
f / 4b / 353ac7303854033
Le répertoire de niveau supérieur est le premier chiffre hexadécimal, le deuxième niveau est les deux chiffres hexadécimaux suivants et le nom de fichier est le chiffre hexadécimal restant.
la source
Vous avez une meilleure solution - utilisez un système de fichiers différent, il y en a beaucoup disponibles, dont beaucoup sont optimisés pour différentes tâches. Comme vous l'avez souligné, ReiserFS est optimisé pour gérer de nombreux fichiers dans un répertoire.
Voir ici pour une comparaison des systèmes de fichiers.
Soyez juste heureux que vous ne soyez pas bloqué avec NTFS qui est vraiment épouvantable pour beaucoup de fichiers dans un répertoire. Je recommanderais JFS en remplacement si vous ne souhaitez pas utiliser le FS4 ext4 relativement nouveau (mais apparemment stable).
la source
L'image de profil est-elle petite? Qu'en est-il de le mettre dans la base de données avec le reste des données de profil? Ce n'est peut-être pas la meilleure option pour vous, mais cela vaut la peine d'être considéré ...
Voici un livre blanc Microsoft (plus ancien) sur le sujet: Vers BLOB ou pas vers BLOB .
la source
J'ai piraté ensemble une petite galerie Web, où je me suis retrouvé avec une variation de ce problème; Je n'avais "que" environ 30 000 images dans le répertoire de cache, ce qui s'est avéré assez lent (ext2 utilise des listes liées pour les index de répertoire, si je me souviens bien).
J'ai fini par faire quelque chose dans ce sens:
Cela partitionnera les données dans 256 répertoires, ce qui donnera une recherche de répertoire rapide pour chacun des trois niveaux.
la source
Ce n'est pas une réponse immédiate à votre problème, mais quelque chose à surveiller pour référence future est le projet lié à OpenBSD appelé 'Epitome'
Epitome est un moteur qui fournit des services de stockage à instance unique, de stockage adressable de contenu et de déduplication.
Toutes vos données sont stockées dans un magasin de données sous forme de blocs hachés, supprimant les blocs non uniques pour réduire l'utilisation de l'espace, et vous permet essentiellement d'oublier le mécanisme de stockage car vous pouvez simplement demander le contenu du magasin de données par UUID.
Epitome est actuellement expérimental, mais quelque chose à surveiller pour l'avenir.
la source
Généralement, vous voulez éviter d'avoir des répertoires contenant un grand nombre de fichiers / répertoires. La raison principale est que l'expansion des caractères génériques sur la ligne de commande entraînera des erreurs "Trop d'arguments" entraînant beaucoup de douleur lors de la tentative de travail avec ces répertoires.
Optez pour une solution qui crée un arbre plus profond mais plus étroit, par exemple en créant des sous-dossiers comme d'autres l'ont décrit.
la source
Nous avons eu un problème similaire, la solution - comme mentionné précédemment - est de créer une hiérarchie de répertoires.
Bien sûr, si vous avez une application complexe qui repose sur une structure de répertoire plate, vous aurez probablement besoin de beaucoup de correctifs. Il est donc bon de savoir qu'il existe une solution de contournement, utilisez des liens symboliques qui n'ont pas la limite de 32 Ko mentionnée. Ensuite, vous avez beaucoup de temps pour réparer l'application ...
la source
Pourquoi ne pas utiliser une approche d'horodatage, puis avoir une option de débordement.
Par exemple
Disons donc que votre horodatage est: 1366587600
Omettez les 2 derniers chiffres (sinon cela devient un peu ridicule). Séparez le tampon en ensembles de 4 (le nombre de répertoires ne doit pas dépasser 9 999 - si vous le souhaitez, vous pouvez le séparer différemment).
Cela devrait vous laisser quelque chose comme ceci:
Ensuite, vérifiez également le montant dans le répertoire avant le téléchargement, s'il obtient un grand nombre de téléchargements (c'est-à-dire 32000 + par 100 secondes), puis parcourez le répertoire par la seconde ou une lettre, par exemple:
ou
Ensuite, connectez l'horodatage + la lettre ou le code de chemin complet dans une base de données avec l'utilisateur et vous devriez être défini.
pathstamp: 1366587600 ou 13665876a (si vous utilisez des lettres).
Cela se retrouve avec un grand nombre de répertoires, mais cela peut être très utile pour gérer les révisions de fichiers. Par exemple, si un utilisateur souhaite utiliser une nouvelle photo de profil, vous avez toujours l'ancienne version horodatée de l'ancienne au cas où il souhaiterait annuler les modifications (ce n'est pas seulement écrasé).
la source
Je suggère de décider combien de sous-répertoires maximum vous voulez (ou pouvez) avoir dans le dossier parent.
Ensuite, vous devez convertir votre ID utilisateur pour qu'il commence à partir de 1.
Ensuite, vous pouvez faire:
modulo = currentId % numberOfSubdirectories
modulo
contiendra désormais votre numéro de sous-répertoire qui ne sera jamais supérieur à celui quenumberOfSubdirectories
vous avez choisi.Faites ce que vous voulez avec modulo, hachez-le, par exemple.
De cette façon, les sous-répertoires seront également remplis de façon linéaire.
la source