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 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?
Réponses:
Je vous recommande d'utiliser un système de fichiers standard au lieu de bases de données. L'utilisation du système de fichiers est plus simple 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 parfaitement fonctionner 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 capable de générer un chemin à partir du numéro de séquence. par exemple:
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 changer une fonction que de changer 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:
12345
->000000012345.jpg
000000012345
->000/000/012
123
est000/000/012/00000000012345.jpg
12345678901234
le chemin serait123/456/789/12345678901234.jpg
Quelques éléments à prendre en compte concernant la structure des répertoires et le stockage des fichiers:
la source
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 liés au stockage de fichiers volumineux 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 épaves de train. J'ai plus de pratique dans l'écriture de scripts dbcc et dans la restauration de tables à partir de sauvegardes que n'importe quelle personne normale devrait en 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.
la source
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.
Supposons que vous ayez un hachage de 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 toujours 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.
la source
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 1 000 par répertoire. Plus vous ajoutez de niveaux de répertoire, 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 contient plus de détails sur la configuration de 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 devriez également chercher à désactiver les fonctionnalités de système de fichiers dont vous n’avez pas besoin (par exemple, la dernière heure d’accès). http://www.pctools.com/guides/registry/detail/50/
la source
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épertoire 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:
Le 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.
Le grand avantage de cette solution est que la structure de répertoires agit efficacement comme un hashtable / dictionary. Avec 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.
la source
Je voudrais les stocker sur le système de fichiers, mais cela dépend de la vitesse à laquelle le nombre de fichiers va augmenter. 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 .
la source
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.
la source
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.
la source
Le nouveau MS SQL 2008 intègre une nouvelle fonctionnalité appelée FILESTREAM. Regarde:
Présentation de Microsoft TechNet FILESTREAM
la source
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 par atteindre un million d'images TOTAL ou continueront-ils à se développer 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épertoires:
Mois, année, même jour est bon pour les images de type sécurité. Je ne suis pas sûr que ce soit 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 ... Ainsi, 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 la date que j'ai donnée?
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. Vous pourrez ainsi 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 permettent 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.
la source
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 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.
la source
Peut-être un schéma de nommage basé sur la date de création: soit en incluant toutes les informations dans le nom du fichier, soit (mieux pour naviguer plus tard) en le divisant en répertoires. Je peux penser aux éléments suivants, en fonction de la fréquence à laquelle vous générez des images:
Year/Month/Day/Hour_Minute_Second.png
Year/Month/Day_Hour_Minute_Second.png
etc. Vous obtenez mon point ... =)
la source
Year/Month/Day/Hour/Minute
- décidez du nombre de niveaux de dossiers dont vous avez besoin en fonction de la fréquence à laquelle les images sont générées lorsque le taux est le plus élevé - et ne créez pas de dossiers qui seraient laissés vides.Je serais enclin à créer une structure de dossiers basée sur la date, par exemple, \ year \ month \ day, et à utiliser des horodatages pour les noms de fichiers. Si nécessaire, les horodatages peuvent avoir un composant compteur supplémentaire si les images doivent être créées si rapidement qu'il peut y en avoir plus d'une par milliseconde. En utilisant une séquence de plus en plus significative pour le tri des noms, la recherche et la maintenance deviennent un jeu d'enfant. par exemple hhmmssmm [seq] .jpg
la source
Envisagez-vous une récupération après sinistre?
Certaines des solutions proposées ici finissent par modifier le nom du fichier (de telle sorte que si le fichier physique était déplacé, vous perdriez la trace du fichier en question). Je recommande de conserver un nom de fichier physique unique afin que, si votre liste principale d'emplacement de fichier soit corrompue, vous puissiez la régénérer avec un petit shell, euh, PowerShell, script;)
D'après ce que j'ai lu ici, il semble que tous ces fichiers seraient stockés sur un système de fichiers. Pensez à les stocker sur plusieurs systèmes de fichiers sur plusieurs ordinateurs. Si vous avez les ressources, déterminez un système permettant de stocker chaque fichier sur deux machines différentes au cas où vous perdriez une source d'alimentation et que le remplacement se fasse dans les 2 jours.
Déterminez les types de procédures à créer pour migrer des fichiers entre des ordinateurs ou des systèmes de fichiers. La possibilité de faire cela avec votre système est en direct et en ligne peut vous éviter des maux de tête considérables sur la route.
Vous pouvez envisager d'utiliser un GUID en tant que nom de fichier physique au lieu d'un numéro incrémentiel au cas où votre compteur de numéros incrémentiels (la colonne d'identité de la base de données?) Serait foiré.
Si nécessaire, envisagez d'utiliser un CDN tel qu'Amazon S3.
la source
Bien que je n'aie pas servi d'images de cette envergure, j'ai déjà écrit une petite application de galerie pour servir environ 25 000 images sur une machine à 400 MHz w. 512 Mo de RAM ou plus. Quelques expériences;
Évitez les bases de données relationnelles à tout prix; Bien que les bases de données soient intelligentes pour la gestion des données, elles ne sont pas conçues pour un tel usage (nous avons des bases de données clé-valeur spécialisées et hiérarchiques pour ce système appelé système de fichiers ). Bien que je n’aie rien d’autre qu’un pressentiment, je parierais que le cache de la base de données disparaît par la fenêtre, si vous lui lancez de gros blobs. Alors que mon matériel disponible était petit, ne pas toucher à la base de données lors de la recherche d’image donnait une vitesse supérieure à des ordres de grandeur.
Recherchez le comportement du système de fichiers. sur ext3 (ou était-ce ext2 à l'époque - je ne m'en souviens pas), la limite de capacité à rechercher efficacement des sous-répertoires et des fichiers se situait autour de 256; il n’ya donc que beaucoup de fichiers et de dossiers dans un dossier donné. Encore une fois, accélération notable. Bien que je ne connaisse pas NTFS, des choses comme XFS (qui utilise des arbres B, si je me souviens bien) sont extrêmement rapides, tout simplement parce qu’elles peuvent effectuer des recherches extrêmement rapidement.
Distribuez les données de manière uniforme. Lorsque j'ai essayé ce qui précède, j'ai essayé de répartir les données uniformément sur tous les répertoires (j'ai créé un MD5 de l'URL et je l'ai utilisé pour les répertoires;
/1a/2b/1a2b...f.jpg
). De cette façon, il faut plus de temps pour atteindre la limite de performance (et le cache du système de fichiers est vide pour des ensembles de données aussi volumineux). (au contraire, vous voudrez peut-être voir où les limites sont précoces; ensuite, vous voulez tout jeter dans le premier répertoire disponible.la source
Pourrait être en retard au jeu à ce sujet. Mais une solution (si cela convient à votre cas d'utilisation) pourrait être le hachage du nom de fichier. C'est un moyen de créer un chemin de fichier facilement reproductible en utilisant le nom du fichier tout en créant une structure de répertoires bien distribuée. Par exemple, vous pouvez utiliser les octets du hashcode du nom de fichier comme chemin:
Cela aurait pour résultat que le chemin soit:
Vous pouvez ensuite trouver
cat.gif
dans la structure de répertoires en reproduisant l'algorithme.Utiliser HEX comme noms de répertoire serait aussi simple que de convertir les
int
valeurs:Résultant en:
J'ai écrit un article à ce sujet il y a quelques années et je l'ai récemment déplacé vers Medium. Il contient quelques informations supplémentaires et un exemple de code: Hachage de noms de fichiers: création d'une structure de répertoire hachée . J'espère que cela t'aides!
la source
Si vous êtes sur Windows, que diriez-vous d’un fichier exFat
http://msdn.microsoft.com/en-us/library/aa914353.aspx
il a été conçu pour stocker des fichiers multimédias et est disponible dès maintenant.
la source
Si TOUTES ne sont pas immédiatement nécessaires et que vous pouvez les générer à la volée et qu'il s'agisse de petites images, pourquoi ne pas implémenter une mémoire cache LRU ou un cache disque au-dessus de votre générateur d'images?
Cela pourrait vous sauver de la mémoire et garder les images chaudes à être servies de mem?
la source
Je viens de faire un test sur zfs parce que j'adore zfs, et j'avais une partition de 500gig sur laquelle j'avais une compression. J'ai écrit un script qui générait 50 à 100 000 fichiers et les plaçais dans des répertoires imbriqués 1/2/3/4/5/6/7/8 (5 à 8 niveaux de profondeur) et le laissais fonctionner pendant une semaine, à mon avis. (Ce n'était pas un bon script.) Il remplit le disque et finit par avoir environ 25 millions de fichiers. L'accès à n'importe quel fichier avec un chemin connu était instantané. La liste de tous les répertoires avec un chemin connu était instantanée.
Obtenir un décompte de la liste des fichiers a cependant pris (via find) 68 heures.
J'ai également fait un test en mettant beaucoup de fichiers dans un seul répertoire. Je me suis levé à environ 3,7 millions de fichiers dans un répertoire avant de m'arrêter. Lister le répertoire pour obtenir un compte a pris environ 5 minutes. La suppression de tous les fichiers de ce répertoire a pris 20 heures. Mais la recherche et l'accès à n'importe quel fichier étaient instantanés.
la source
Je vois que d’autres mentionnent une base de données, mais je ne vois aucune mention de cela dans votre message. Dans tous les cas, mon opinion sur ce point est la suivante: soit vous en tenez à une base de données ou à un système de fichiers. Si vous devez mélanger les deux, faites attention. Les choses se compliquent. Mais vous devrez peut-être. Stocker un million de photos dans une base de données ne semble pas la meilleure idée.
La spécification suivante pourrait vous intéresser. La plupart des appareils photo numériques la suivent pour gérer le stockage des fichiers: https://en.wikipedia.org/wiki/Camera_Image_File_Format
Essentiellement, un dossier est créé, tel que
000OLYMPUS
et des photos sont ajoutées à ce dossier (par exempleDSC0000.RAW
). Lorsque le compteur de noms de fichier atteintDSC9999.RAW
un nouveau dossier est créé (001OLYMPUS
) et une image est ajoutée à nouveau, en réinitialisant le compteur, éventuellement avec un préfixe différent (ex:)P_0000.RAW
.Alternativement, vous pouvez également créer des dossiers basés sur des parties du nom de fichier (déjà mentionné à plusieurs reprises). Par exemple, si votre photo est nommée
IMG_A83743.JPG
, stockez-la dansIMG_\A8\3\IMG_A83743.JPG
. Il est plus compliqué à mettre en œuvre mais rendra vos fichiers plus faciles à trouver.Selon le système de fichiers (cela nécessitera des recherches), vous pourrez peut-être vider toutes les images dans un seul dossier, mais, selon mon expérience, cela causerait généralement des problèmes de performances.
la source
Vous voudrez peut-être regarder ZFS (système de fichiers, gestionnaire de volumes de Sun) Cordialement
la source
Un moyen propre de générer le chemin à partir d'un grand nombre est de le convertir facilement en hex puis de le diviser!
par exemple
1099496034834
>0xFFFF1212
>FF/FF/12/12
Stocker et charger:
Codes sources complets: https://github.com/acrobit/AcroFS
la source
Malheureusement, les systèmes de fichiers gèrent un grand nombre de petits fichiers (performances avec plusieurs fichiers par répertoire ou arborescences de répertoires profonds, vérification des temps de redémarrage, fiabilité). La solution ci-dessus impliquant des fichiers ZIP est donc préférable si vous souhaitez utiliser un système de fichiers.
L'utilisation d'un gestionnaire de base de données est de loin la meilleure option. un simple comme BDB ou GDBM par exemple; Même un SGBD relatif comme MySQL serait mieux. Seules les personnes paresseuses qui ne comprennent pas les systèmes de fichiers et les bases de données (par exemple, celles qui rejettent des transactions) ont tendance à utiliser les systèmes de fichiers comme bases de données (ou un peu plus rarement, vice-versa).
la source
Que diriez-vous d'une base de données avec une table contenant un ID et un BLOB pour stocker l'image? Vous pouvez ensuite ajouter de nouvelles tables chaque fois que vous souhaitez associer d'autres éléments de données à une photo.
Si vous vous attendez à évoluer, pourquoi ne pas évoluer maintenant? Vous gagnerez du temps à la fois maintenant et plus tard, IMO. Implémentez la couche base de données une fois, ce qui est assez facile pour commencer. Ou implémentez quelque chose avec des dossiers et des noms de fichiers et blah blah blah, puis passez à autre chose lorsque vous commencez à faire sauter MAX_PATH.
la source