Question Stocker un million d'images dans le système de fichiers


J'ai un projet qui va générer un grand nombre d'images. Environ 1.000.000 pour commencer. Ce ne sont pas de grandes images, je vais donc les stocker toutes sur une seule machine au début.

Comment recommandez-vous de stocker ces images efficacement? (Système de fichiers NTFS actuellement)

J'envisage un schéma de nommage ... pour commencer toutes les images auront un nom incrémental à partir de 1 J'espère que cela m'aidera à les trier plus tard si nécessaire et à les jeter dans des dossiers différents.

Quel serait un meilleur schéma de nommage:

a / b / c / 0 ... z / z / z / 999

ou

a / b / c / 000 ... z / z / z / 999

une idée à ce sujet?


75
2017-12-17 16:52


origine


Sont-ils liés à des utilisateurs spécifiques ou simplement génériques? Sont-ils regroupés de quelque manière que ce soit?
seulement générique. un tas d'images générées par certains équipements techniques. Je les nomme progressivement à partir de 1 juste pour avoir l’idée d’une référence temporelle. - s.mihai
Comment vont-ils être utilisés / consultés? via une application sur mesure ou quoi? - dove
Est-ce toi? i46.tinypic.com/1z55k7q.jpg
:)) oui ... 1 mil. images porno :)) - s.mihai


Réponses:


Je vous recommande d'utiliser un système de fichiers standard au lieu de bases de données. Utiliser un système de fichiers est plus facile qu’une base de données, vous pouvez utiliser des outils normaux pour accéder aux fichiers, les systèmes de fichiers sont conçus pour ce type d’utilisation, etc. NTFS devrait fonctionner parfaitement comme système de stockage.

Ne stockez pas le chemin d'accès réel à la base de données. Il est préférable de stocker le numéro de séquence de l’image dans la base de données et d’avoir une fonction qui peut générer un chemin à partir du numéro de séquence. par exemple:

 File path = generatePathFromSequenceNumber(sequenceNumber);

Il est plus facile à gérer si vous devez modifier la structure des répertoires. Peut-être avez-vous besoin de déplacer les images vers un autre emplacement, peut-être que vous manquez d'espace et que vous commencez à stocker certaines images sur le disque A et d'autres sur le disque B, etc. Il est plus facile de modifier une fonction que de modifier les chemins d'accès dans la base de données .

J'utiliserais ce type d'algorithme pour générer la structure de répertoires:

  1. Premièrement, complétez votre numéro de séquence avec des zéros au début jusqu'à ce que vous ayez au moins 12 caractères. Ceci est le nom de votre fichier. Vous voudrez peut-être ajouter un suffixe:
    • 12345 -> 000000012345.jpg
  2. Divisez ensuite la chaîne en blocs de 2 ou 3 caractères, chaque bloc désignant un niveau de répertoire. Avoir un nombre fixe de niveaux de répertoires (par exemple 3):
    • 000000012345 -> 000/000/012
  3. Stockez le fichier dans le répertoire généré:
    • Ainsi, le chemin complet et le nom du fichier pour le fichier avec l'ID de séquence 123 est 000/000/012/00000000012345.jpg
    • Pour fichier avec identifiant de séquence 12345678901234 le chemin serait 123/456/789/12345678901234.jpg

Quelques éléments à prendre en compte concernant les structures de répertoire et le stockage de fichiers:

  • L'algorithme ci-dessus vous donne un système où chaque répertoire feuille contient au maximum 1000 fichiers (si vous avez moins de 1 000 000 000 000 fichiers au total)
  • Il peut y avoir des limites au nombre de fichiers et sous-répertoires qu'un répertoire peut contenir, par exemple Système de fichiers ext3 sous Linux a une limite de 31998 sous-répertoires par répertoire.
  • Les outils normaux (WinZip, l'Explorateur Windows, la ligne de commande, le shell bash, etc.) risquent de ne pas très bien fonctionner si vous avez un grand nombre de fichiers par répertoire (> 1000).
  • La structure de répertoire elle-même prendra un peu d’espace disque, vous ne voudrez donc pas trop de répertoires.
  • Avec la structure ci-dessus, vous pouvez toujours trouver le chemin correct pour le fichier image en regardant simplement le nom du fichier, si vous endommagez la structure de votre répertoire.
  • Si vous devez accéder à des fichiers de plusieurs ordinateurs, envisagez de les partager via un système de fichiers réseau.
  • La structure de répertoire ci-dessus ne fonctionnera pas si vous supprimez beaucoup de fichiers. Il laisse des "trous" dans la structure de répertoires. Mais puisque vous ne supprimez aucun fichier, ça devrait aller.

70
2017-12-17 17:32



très intéressant! scinder le nom du fichier ... je n'y avais pas pensé. Je suppose que c'est la façon élégante de le faire: -? - s.mihai
L'utilisation d'un hachage (tel que MD5) comme nom du fichier, ainsi que la distribution du répertoire, fonctionneraient. L'intégrité des fichiers ne constitue pas seulement un avantage supplémentaire du schéma de dénomination (facile à vérifier), mais vous bénéficiez d'une distribution raisonnablement égale dans toute la hiérarchie des répertoires. Donc, si vous avez un fichier nommé "f6a5b1236dbba1647257cc4646308326.jpg", vous le stockerez dans "/ f / 6" (ou aussi profond que vous le souhaitez). 2 niveaux de profondeur donne 256 répertoires, soit un peu moins de 4000 fichiers par répertoire pour les fichiers initiaux de 1 m. Il serait également très facile d’automatiser la redistribution dans un schéma plus détaillé.
+1 Je viens de remarquer que cette réponse était similaire à celle que je viens de publier. - 3dinfluence
Je suis tout à fait d’accord pour utiliser le système de fichiers et créer un identifiant artificiel pour "découper" les noms de dossiers. Mais vous devriez également essayer d’obtenir une distribution aléatoire d’identifiants, c’est-à-dire n’utilisez pas de numéro de séquence. Cela vous permettrait d'avoir une arborescence de dossiers plus équilibrée. De plus, avec une distribution aléatoire, vous pouvez plus facilement partitionner l'arborescence sur plusieurs systèmes de fichiers. J'utiliserais également un réseau SAN basé sur ZFS avec déduplication activée et un volume fragmenté pour chaque système de fichiers. Vous pouvez toujours utiliser NTFS en utilisant iSCSI pour accéder au réseau de stockage. - Michael Dillon
Si vous allez de droite à gauche à l'étape 2, les fichiers sont répartis de manière égale. Aussi, ne vous inquiétez pas du fait que vous ne remplissez pas suffisamment de zéros, vous pouvez disposer d’un nombre illimité de fichiers. - ropo


Je vais mettre mes 2 cents sur un conseil négatif: n'allez pas avec une base de données.

Je travaille avec des bases de données de stockage d'images depuis des années: fichiers volumineux (1 Mo -> 1 Go), souvent modifiés, multiples versions du fichier, auxquelles on accède assez souvent. Les problèmes de base de données que vous rencontrez avec des fichiers volumineux stockés sont extrêmement fastidieux, les problèmes d'écriture et de transaction sont épineux et vous rencontrez des problèmes de verrouillage qui peuvent causer de graves problèmes de train. épaves. J'ai plus de pratique dans l'écriture de scripts dbcc et la restauration de tables à partir de sauvegardes que n'importe quelle personne normale déjà avoir.

La plupart des systèmes plus récents avec lesquels j'ai travaillé ont poussé le stockage de fichiers vers le système de fichiers et ne s'appuient que sur des bases de données pour l'indexation. Les systèmes de fichiers sont conçus pour supporter ce type d'abus, ils sont beaucoup plus faciles à développer et vous perdez rarement tout le système de fichiers si une entrée est corrompue.


29
2017-12-17 17:12



Oui. note prise! - s.mihai
Avez-vous examiné le type de données FILESTREAM de SQL 2008? C'est un croisement entre la base de données et le stockage du système de fichiers. - NotMe
Utilisez +1 pour coller au serveur de fichiers plutôt qu’à une base de données car vous effectuez des opérations d’E / S rapides et peu fréquentes.
Que se passe-t-il si vous ne stockez que quelques centaines de documents ou de photos par base de données - aucun inconvénient à utiliser une base de données pour le stockage? - Beep beep
+1 ... un système de fichiers est quand même une sorte de "base de données" (ntfs bien sûr), alors pourquoi le rendre trop compliqué. - akira


Je pense que la plupart des sites qui traitent de ce problème utilisent un hachage pour s’assurer que les fichiers sont répartis de manière égale dans les dossiers.

Alors disons que vous avez un hachage d'un fichier qui ressemble à ceci 515d7eab9c29349e0cde90381ee8f810
Vous pourriez l'avoir stocké à l'emplacement suivant et vous pouvez utiliser le nombre de niveaux dont vous avez besoin pour limiter le nombre de fichiers dans chaque dossier.
\51\5d\7e\ab\9c\29\349e0cde90381ee8f810.jpg

J'ai vu cette approche prise à plusieurs reprises. Vous avez encore besoin d'une base de données pour mapper ces hachages de fichiers sur un nom lisible par l'homme et sur les métadonnées que vous avez besoin de stocker. Mais cette approche évolue assez bien parce que vous pouvez commencer à distribuer l’espace d’adresse de hachage entre plusieurs ordinateurs et / ou pools de stockage, etc.


12
2017-12-17 20:17



Git utilise une approche similaire: git-scm.com/book/en/v2/Git-Internals-Git-Objects (pour sauvegarder cette réponse) - aexl


Idéalement, vous devez exécuter des tests sur des temps d'accès aléatoires pour différentes structures, car la configuration de votre disque dur, la mise en cache, la mémoire disponible, etc. peuvent modifier ces résultats.

En supposant que vous ayez le contrôle sur les noms de fichiers, je les partitionnerais au niveau de 1000 par répertoire. Plus vous ajoutez de niveaux de répertoires, plus vous gravez d'inodes, il y a donc un push-pull ici.

Par exemple.,

/ root / [0-99] / [0-99] / nom_fichier

Remarque, http://technet.microsoft.com/en-us/library/cc781134(WS.10).aspx a plus de détails sur la configuration NTFS. En particulier, "Si vous utilisez un grand nombre de fichiers dans un dossier NTFS (300 000 ou plus), désactivez la génération de noms de fichiers courts pour obtenir de meilleures performances, en particulier si les six premiers caractères des noms de fichiers longs sont similaires."

Vous devez également vous pencher sur la désactivation des fonctionnalités de système de fichiers dont vous n’avez pas besoin (par exemple, l'heure du dernier accès). http://www.pctools.com/guides/registry/detail/50/


11
2017-12-17 17:01



+1 pour désactiver la génération de nom de fichier 8.3 et l'heure du dernier accès; ce sont les premières choses qui me viennent à l’esprit lorsque j’ai lu «grand nombre de [fichiers]» et «NTFS» (Windows). - rob
lien vers le bas ........................ - Pacerier


Quoi que vous fassiez, ne les stockez pas tous dans un seul répertoire.

En fonction de la distribution des noms de ces images, vous pouvez créer une structure de répertoires dans laquelle vous avez des dossiers de lettre unique de premier niveau, dans lesquels vous disposerez d'un autre ensemble de sous-dossiers pour la deuxième lettre d'images, etc.

Alors:

Dossier img\a\b\c\d\e\f\g\ contiendrait les images commençant par 'abcdefg' et ainsi de suite.

Vous pouvez introduire votre propre profondeur appropriée requise.

L’avantage de cette solution est que la structure de répertoires se comporte effectivement comme un hashtable / dictionary. Si vous avez un nom de fichier image, vous connaîtrez son répertoire et un répertoire, vous connaîtrez un sous-ensemble d’images qui y vont.


7
2017-12-17 16:58



\ a \ b \ c \ d \ e \ f \ i je le fais maintenant, je pensais qu'il y avait un moyen sage de le faire. - s.mihai
C'est une solution généralement acceptée de la façon de les stocker physiquement. Générer clairement les URL de l'image est quelque chose qui peut être facilement fait de manière dynamique en fonction du nom du fichier image. En outre, pour les servir, vous pouvez même introduire des sous-domaines img-a, img-b sur le serveur d'images si vous le souhaitez, pour accélérer les temps de chargement.
Et +1 pour "ne les stockez pas tous dans un seul répertoire". Je prends en charge un système hérité qui a placé plus de 47 000 fichiers sur un serveur dans un seul dossier, et il faut environ une minute à Explorer pour ouvrir le dossier. - Mark Ransom
Faire un \ b \ c \ d \ e \ f \ g rend la structure de répertoires très profonde et chaque répertoire ne contient que quelques fichiers. Mieux vaut utiliser plus d’une lettre par niveau de répertoire, par exemple. ab \ cd \ ef \ ou abc \ def \. Les répertoires prennent également de la place sur le disque, vous ne voulez donc pas en avoir trop. - Juha Syrjälä
Je devais prendre en charge une application contenant plus de 4 millions de fichiers dans un seul répertoire. cela a fonctionné étonnamment bien, mais vous ne pouviez JAMAIS que l'explorateur ouvre le dossier, il trierait continuellement les nouveaux ajouts. +1 pour NTFS pouvant le gérer sans mourir. - SqlACID


Je voudrais les stocker sur le système de fichiers, mais cela dépend de la vitesse à laquelle le nombre de fichiers augmentera. Ces fichiers sont-ils hébergés sur le Web? Combien d'utilisateurs accéderaient à ce fichier? Ce sont les questions auxquelles il faut répondre avant que je puisse vous donner une meilleure recommandation. Je voudrais aussi regarder Haystack de Facebook, ils ont une très bonne solution pour stocker et servir des images.

De plus, si vous choisissez le système de fichiers, vous devrez partitionner ces fichiers avec des répertoires. J'ai examiné cette question et proposé une solution, mais ce n'est pas une solution parfaite, loin de là. Je partitionne par table de hachage et les utilisateurs peuvent en lire plus sur mon Blog.


5
2017-12-17 16:59



les images ne sont pas destinées à un accès fréquent. donc il n'y a pas de problème avec cela. leur nombre augmentera assez vite. Je suppose qu'il y aura le 1mil. marquer dans 1 mois. - s.mihai
je suis intéressé par la vue programmeur afin que je ne pense pas trop cela trop - s.mihai
Donc, si vous n'avez pas besoin d'un accès rapide, Haystack n'est probablement pas pour vous. Utiliser des répertoires pour les partitions est la solution la plus simple à mon sens. - Lukasz


Nous avons un système de magasin de photos avec 4 millions d'images. Nous utilisons la base de données uniquement pour les métadonnées et toutes les images sont stockées sur le système de fichiers à l'aide d'un système de dénomination inversée, où les noms de dossier sont générés à partir du dernier chiffre du fichier, last-1, etc. par exemple.: 000001234.jpg est stocké dans une structure de répertoires telle que 4 \ 3 \ 2 \ 1 \ 000001234.jpg.

Ce schéma fonctionne très bien avec l’index d’identité de la base de données, car il remplit uniformément la structure de répertoires.


5
2017-12-30 22:10





Point rapide, vous n'avez pas besoin de stocker un chemin de fichier dans votre base de données. Vous pouvez simplement stocker une valeur numérique, si vos fichiers sont nommés de la manière que vous décrivez. Ensuite, en utilisant l’un des schémas de stockage bien définis déjà décrits, vous pouvez obtenir l’index sous forme de nombre et retrouver très rapidement le fichier en parcourant la structure de répertoires.


4
2017-12-17 17:18



: -? bon point rapide. juste que maintenant je n'ai pas d'algorithme pour générer le chemin. - s.mihai


Le nouveau MS SQL 2008 intègre une nouvelle fonctionnalité appelée FILESTREAM. Regarde:

Présentation de Microsoft TechNet FILESTREAM


4
2017-12-17 17:24





Vos images devront-elles porter un nom unique?  Le processus qui génère ces images peut-il générer plusieurs fois le même nom de fichier? Difficile à dire sans savoir quel périphérique crée le nom de fichier, mais il est «réinitialisé» et lors du redémarrage, il commence à nommer les images comme il l'avait fait la dernière fois qu'il a été réinitialisé - si cela pose un problème.

En outre, vous dites que vous atteindrez 1 million d'images dans un mois. Et après ça? À quelle vitesse ces images continueront-elles à remplir le système de fichiers?  Vont-ils finir à un moment donné et se stabiliser à environ 1 million d’images TOTAL ou va-t-il continuer à grandir et grandir, mois après mois? 

Je vous le demande parce que vous pouvez commencer à concevoir votre système de fichiers par mois, puis par image. Je pourrais être enclin à vous suggérer de stocker les images dans une telle structure de répertoire:

imgs\yyyy\mm\filename.ext

where: yyyy = 4 digit year
         mm = 2 digit month

example:  D:\imgs\2009\12\aaa0001.jpg
          D:\imgs\2009\12\aaa0002.jpg
          D:\imgs\2009\12\aaa0003.jpg
          D:\imgs\2009\12\aaa0004.jpg
                   |
          D:\imgs\2009\12\zzz9982.jpg
          D:\imgs\2010\01\aaa0001.jpg (this is why I ask about uniqueness)
          D:\imgs\2010\01\aab0001.jpg

Mois, année, même jour est bon pour les images de type sécurité. Je ne sais pas si c'est ce que vous faites, mais je l'ai fait avec une caméra de sécurité pour la maison qui prenait une photo toutes les 10 secondes ... De cette manière, votre application peut accéder à une heure précise ou même à une plage dans laquelle vous pourriez penser que l'image a été générée. . Ou, au lieu d'année, de mois, existe-t-il un autre "sens" pouvant être dérivé du fichier image lui-même? Quelques autres descripteurs, autres que l'exemple de date que j'ai donné?

Je ne voudrais pas stocker les données binaires dans la base de données. Jamais eu de bonnes performances / chance avec ce genre de chose. Je ne peux pas imaginer que cela fonctionne bien avec 1 million d’images. Je voudrais stocker le nom de fichier et c'est tout. S'ils vont tous être au format JPG, ne stockez même pas l'extension. Je créerais une table de contrôle qui stockerait un pointeur sur le serveur, le lecteur, le chemin d'accès, etc. du fichier. De cette façon, vous pourrez déplacer ces images dans une autre boîte tout en les localisant. Avez-vous besoin de taguer vos images par mots-clés?   Si tel est le cas, vous souhaitez créer les tables appropriées qui autorisent ce type de marquage.

Vous (ou d’autres) avez peut-être abordé ces idées pendant que je répondais. J'espère que cela vous aidera.


4
2017-12-17 18:24



1.tous les fichiers seront nommés de manière unique. 2.Le système va grandir et grandira au début, il sortira environ 1 million d'images puis grossira au rythme de quelques dizaines de milliers par mois. 3.il y aura une sorte de marquage des fichiers à un moment donné dans le futur, c'est pourquoi je veux stocker une sorte de données d'identification dans la base de données. - s.mihai


Je participe à un projet qui stocke 8,4 millions d'images au cours d'une année pour documenter le statut de divers périphériques. Les images les plus récentes sont consultées plus fréquemment et les images plus anciennes sont rarement recherchées, à moins de découvrir une condition qui aurait incité quelqu'un à consulter les archives.

Ma solution, basée sur cet usage, consistait à compresser les images en fichiers compressés. Les images sont au format JPG, chacune d'environ 20 Ko et ne se compressent pas beaucoup, de sorte que le schéma de compression ZIP est nul. Ceci est fait simplement pour les concaténer dans une entrée de système de fichiers, ce qui aide grandement NTFS en termes de rapidité lorsqu'il s'agit de les déplacer d'un lecteur à l'autre ou de parcourir la liste des fichiers.

Les images plus anciennes qu'un jour sont combinées dans un zip "quotidien"; les zips âgés de plus d'un mois sont combinés dans leur zip "mensuel" respectif; et finalement tout ce qui dépasse l'année n'est plus nécessaire et par conséquent supprimé.

Ce système fonctionne bien, car les utilisateurs peuvent parcourir les fichiers (via le système d’exploitation ou un certain nombre d’applications client) et tout est nommé en fonction des noms de périphérique et des horodatages. Généralement, un utilisateur connaît ces deux informations et peut rapidement localiser l’une des millions d’images.

Je comprends que cela n’est probablement pas lié à vos détails particuliers, mais j’ai pensé que je partagerais.


3
2017-12-17 17:02