Stockage et sauvegarde de 10 millions de fichiers sous Linux

25

Je gère un site Web où environ 10 millions de fichiers (couvertures de livres) sont stockés dans 3 niveaux de sous-répertoires, allant de [0-f]:

0/0/0/
0/0/1/
...
f/f/f/

Cela conduit à environ 2400 fichiers par répertoire, ce qui est très rapide lorsque nous devons récupérer un fichier. C'est d'ailleurs une pratique suggérée par de nombreuses questions .

Cependant, lorsque j'ai besoin de sauvegarder ces fichiers, il faut plusieurs jours pour parcourir les répertoires 4k contenant des fichiers de 10 m.

Je me demande donc si je pourrais stocker ces fichiers dans un conteneur (ou dans des conteneurs 4k), qui agiraient chacun exactement comme un système de fichiers (une sorte de conteneur ext3 / 4 monté?). Je suppose que ce serait presque aussi efficace que d'accéder directement à un fichier dans le système de fichiers, et cela aurait le grand avantage d'être copié sur un autre serveur très efficacement.

Une suggestion sur la meilleure façon de procéder? Ou toute alternative viable (noSQL, ...)?

Benjoin
la source
Quel système de fichiers utilisez-vous actuellement?
cmcginty
NetApp est léché d'être une option si vous pouvez aforter les prix
Ian Ringrose
J'utilise ext4 sous CentOS 5.6
Benjamin
1
Curieux de savoir pourquoi cela devrait prendre "plusieurs jours juste pour parcourir les répertoires 4k contenant des fichiers de 10m", ce qui semble beaucoup trop lent. En supposant 150 octets par nom de chemin, les noms de fichiers de 10 m génèrent 1,5 Go de données, il pourrait donc s'agir de la mémoire / CPU disponible (y compris le tri du résultat). Vérifiez également si l'activation / la désactivation de dir_index aide: lonesysadmin.net/2007/08/17/… ainsi que divers conseils sur serverfault.com/questions/183821/…
RichVel
Remarque 5 ans plus tard: j'ai tout migré vers Amazon S3, ce qui est parfaitement adapté pour stocker une telle quantité de fichiers. De plus, je n'ai plus à diviser les fichiers en 3 niveaux de sous-répertoires, car pour S3, cela ne fait aucune différence (un chemin est un chemin, qu'il contienne ou non des barres obliques). Et je peux mieux dormir, sachant que mes données sont répliquées en toute sécurité sur plusieurs sites.
Benjamin

Réponses:

11

Options pour accéder et sauvegarder rapidement des millions de fichiers

Emprunter auprès de personnes ayant des problèmes similaires

Cela ressemble beaucoup à une sorte de problème plus facile auquel sont confrontés les serveurs de news USENET et les serveurs proxy de mise en cache: des centaines de millions de petits fichiers auxquels on accède de manière aléatoire. Vous voudrez peut-être leur donner un indice (sauf qu'ils ne doivent généralement jamais effectuer de sauvegardes).

http://devel.squid-cache.org/coss/coss-notes.txt

http://citeseer.ist.psu.edu/viewdoc/download;jsessionid=4074B50D266E72C69D6D35FEDCBBA83D?doi=10.1.1.31.4000&rep=rep1&type=pdf

De toute évidence, la nature cyclique du système de fichiers d'actualités cycliques n'est pas pertinente pour vous, mais le concept de niveau inférieur d'avoir plusieurs fichiers / périphériques de disque avec des images compressées et un index rapide des informations que l'utilisateur fournit pour rechercher les informations de localisation est tout à fait approprié.

Systèmes de fichiers dédiés

Bien sûr, ce ne sont que des concepts similaires à ce dont les gens parlaient avec la création d'un système de fichiers dans un fichier et son montage sur le bouclage, sauf que vous pouvez écrire votre propre code de système de fichiers. Bien sûr, puisque vous avez dit que votre système était principalement en lecture, vous pouvez en fait dédier une partition de disque (ou une partition lvm pour plus de flexibilité dans le dimensionnement) à cette seule fin. Lorsque vous souhaitez sauvegarder, montez le système de fichiers en lecture seule, puis faites une copie des bits de partition.

LVM

J'ai mentionné LVM ci-dessus comme étant utile pour permettre le dimensionnement dynamique d'une partition afin que vous n'ayez pas besoin de sauvegarder beaucoup d'espace vide. Mais, bien sûr, LVM a d'autres fonctionnalités qui pourraient être très applicables. Plus précisément, la fonctionnalité "instantané" qui vous permet de figer un système de fichiers à un moment donné. Tout accidentel rm -rfou autre ne perturberait pas l'instantané. Selon ce que vous essayez de faire, cela peut suffire à vos besoins de sauvegarde.

RAID-1

Je suis sûr que vous connaissez déjà le RAID et l'utilisez probablement déjà pour la fiabilité, mais le RAID-1 peut également être utilisé pour les sauvegardes, du moins si vous utilisez le RAID logiciel (vous pouvez l'utiliser avec le RAID matériel, mais en fait vous donne une fiabilité inférieure car il peut nécessiter le même modèle / contrôleur de révision pour lire). Le concept est que vous créez un groupe RAID-1 avec un disque de plus que ce dont vous avez réellement besoin pour vos besoins de fiabilité normaux (par exemple un troisième disque si vous utilisez le logiciel RAID-1 avec deux disques, ou peut-être un gros disque et un matériel) RAID5 avec des disques plus petits avec un logiciel RAID-1 au-dessus du matériel RAID-5). Quand vient le temps de faire une sauvegarde, installez un disque, demandez à mdadm d'ajouter ce disque au groupe de raid, attendez qu'il indique l'intégralité, demandez éventuellement un gommage de vérification, puis retirez le disque. Bien sûr,

Seth Robertson
la source
Réponse très complète, qui résume les bonnes solutions. Je pense que je vais conserver ma structure de système de fichiers existante et utiliser des instantanés LVM, ce qui semble être parfait pour mon cas d'utilisation.
Benjamin
9

Vous pouvez monter un système de fichiers virtuel à l'aide du gestionnaire de bouclage, mais bien que cela accélère votre processus de sauvegarde, cela peut affecter les opérations normales.

Une autre alternative consiste à sauvegarder l'intégralité du périphérique à l'aide de dd. Par exemple dd if=/dev/my_device of=/path/to/backup.dd,.


la source
+1 La sauvegarde de l'appareil lui-même est une bonne idée.
asm
3
Vous devriez, si vous utilisez cette approche, tester la restauration (enfin, vous devriez toujours le faire), car si votre entrée est un disque comme / dev / sdd, dd stockera le sheme et les tailles de partition. Si vous le restaurez sur un disque plus petit, vous obtiendrez des erreurs, et si vous le restaurez sur un disque plus gros, il apparaîtra tronqué. Cela fonctionnera mieux si vous restaurez les données sur un autre exemplaire du même type de disque. La restauration des partitions uniquement (/ dev / sdd1) sera moins gênante.
utilisateur inconnu
1
Notez que si le périphérique est sur LVM, une sauvegarde peut également être effectuée sans démonter le disque à l'aide d'instantanés LVM.
bdonlan
J'appuie l'approche de sauvegarde d'instantanés LVM. J'ai utilisé lvm dans le passé pour la réplication DR en direct. L'utilisation de dd en combinaison avec des instantanés facilite la réalisation de sauvegardes rapides au niveau du bloc.
slashdot
J'ai essayé ddsur ncce qui fait un bon travail! Cependant, je pourrais avoir des données incohérentes / corrompues, par opposition à l'utilisation d'instantanés LVM au lieu de la partition en direct.
Benjamin
8

Comme vous le savez probablement, votre problème est la localité. Une recherche de disque typique prend environ 10 ms. Donc, simplement appeler "stat" (ou open ()) sur 10 millions de fichiers placés au hasard nécessite 10 millions de recherches, soit environ 100 000 secondes, ou 30 heures.

Vous devez donc placer vos fichiers dans des conteneurs plus grands, de sorte que le nombre correspondant soit la bande passante de votre lecteur (50-100 Mo / sec pour un seul disque, généralement) plutôt que votre temps de recherche. Vous pouvez également y lancer un RAID, ce qui vous permet d'augmenter la bande passante (mais pas de réduire le temps de recherche).

Je ne vous dis probablement rien que vous ne sachiez déjà, mais mon point est que votre idée de "conteneur" résoudra certainement le problème, et à peu près n'importe quel conteneur fera l'affaire. Les montures en boucle fonctionneront probablement aussi bien que n'importe quoi.

Nemo
la source
Oui, la localité est cruciale. Regardez vos habitudes d'utilisation. La plupart des problèmes ont tendance à suivre le principe de Pareto (80% des processus atteignant 20% des données), donc si vous pouviez déterminer quels fichiers doivent être mis en cache dans la RAM, ou simplement mettre sur une partition séparée avec une disposition différente des répertoires, donc cela prend moins de recherches de répertoire ou de recherches, cela aiderait probablement beaucoup. La répartition des fichiers fréquemment consultés sur différentes broches de disques afin que les recherches puissent être effectuées en parallèle pourrait également aider. +1 pour @nemo pour avoir évoqué la localité de référence.
Marcin
5

Il y a quelques options. Le plus simple, et devrait fonctionner avec tous les systèmes de fichiers Linux, est de ddcopier la partition entière ( /dev/sdb3ou /dev/mapper/Data-ImageVol) sur une seule image et d'archiver cette image. En cas de restauration de fichiers singuliers, montez en boucle l'image ( mount -o loop /usr/path/to/file /mountpoint) et copiez les fichiers dont vous avez besoin. Pour une restauration complète de partition, vous pouvez inverser le sens de la ddcommande initiale , mais vous avez vraiment besoin d'une partition de taille identique.

À en juger par votre cas d'utilisation, je suppose que les restaurations de fichiers individuelles sont un événement très rare, voire jamais. C'est pourquoi une sauvegarde basée sur une image a vraiment du sens ici. Si vous devez effectuer des restaurations individuelles plus souvent, l'utilisation d'instantanés LVM par étapes sera beaucoup plus pratique; mais vous devez toujours effectuer la sauvegarde basée sur l'image pour les catastrophes critiques "nous avons tout perdu". Les restaurations basées sur l'image ont tendance à aller beaucoup plus vite que les restaurations basées sur tar simplement parce qu'il s'agit simplement de restaurer des blocs, cela n'entraîne pas beaucoup d'opérations de métadonnées à chaque ouverture / fermeture, et peut également être une opération de disque hautement séquentielle pour la vitesse augmente encore.

Alternativement, comme le mentionne la vidéo Google @casey à mi-chemin, XFS est un excellent système de fichiers (s'il est complexe). L'un des meilleurs utilitaires avec XFS est l' xfsdumputilitaire, qui videra un système de fichiers entier dans un seul fichier, et le fera généralement plus rapidement que tarpossible. C'est un utilitaire spécifique au système de fichiers, il peut donc tirer parti des internes fs d'une manière que tar ne peut pas.

sysadmin1138
la source
Beaucoup de bonnes réponses là-bas! XFS semble être intéressant, mais je crains que ce soit un peu hors de ma portée.
Benjamin
2

Peut-être une réponse simpliste, mais ma première pensée a été d'utiliser quelque chose comme GridFS qui est construit sur MongoDB . De nombreux pilotes de langue principale le prennent en charge immédiatement, vous devriez donc pouvoir l'échanger avec les sections de lecture de fichiers de votre code. En outre, vous pouvez simplement faire de vos chemins de répertoire existants les clés de ces fichiers.

Un problème que vous pourriez avoir est que Mongo a tendance à ralentir assez rapidement s'il recherche tout le temps à partir du disque. Avec 10 millions de fichiers, je m'attends à ce que la plupart de vos données soient sur disque. Les morceaux de fichiers dans GridFS sont de 4 Mo, si je me souviens bien, donc si vos fichiers sont plus gros que cela, vous ferez plusieurs opérations coûteuses pour obtenir un fichier. La clé, je pense, serait de partager vos fichiers en fonction de votre structure de répertoires déjà bien rangée afin que vous puissiez avoir plusieurs instances de Mongo en cours d'exécution sur plusieurs boîtes pour alléger la charge. Cependant, je ne sais pas non plus quelles sont vos exigences de performance, donc je pourrais y penser de manière excessive.

Quel est l'avantage de tout cela? Des performances qui correspondent assez étroitement aux lectures de disque si elles sont effectuées correctement. En outre, Mongo propose plusieurs méthodes intégrées pour sauvegarder rapidement la totalité de la bande de données dans une instance de base de données, et même avec la base de données toujours en cours d'exécution.

daveslab
la source
J'aurai certainement un aperçu de GridFS que je ne connaissais pas, mais je pense que je finirai par tout garder basé sur le système de fichiers pour réduire la quantité de travail, car tout fonctionne déjà!
Benjamin
1

Si vous êtes satisfait d'un modèle d'appareil pour votre stockage de données, vous pouvez peut-être envisager NexentaStor . Il exécute ZFS sur OpenSolaris sous le capot, mais toute l'administration se fait via une interface graphique Web.

Il existe quelques fonctionnalités qui pourraient aider à résoudre votre problème.

  • La version Enterprise prend en charge une forme de réplication à distance basée sur des instantanés qui ne nécessite pas de numériser l'ensemble du système de fichiers.

  • Si cela ne vous dérange pas de vous salir les mains, ZFS dispose d'une commande de diff ZFS très pratique qui vous indique efficacement quels fichiers ont été ajoutés, modifiés ou supprimés depuis le dernier instantané, sans avoir besoin de parcourir l'ensemble du système de fichiers. Vous pouvez l'intégrer à votre système de sauvegarde pour réduire considérablement le temps requis pour effectuer des sauvegardes incrémentielles.

Tom Shaw
la source
Merci, allez y jeter un œil. Peut-être que cela ajouterait un peu de complexité à mon projet!
Benjamin
1

Vous pouvez utiliser un dumputilitaire standard pour sauvegarder le système de fichiers EXT4 avec beaucoup de fichiers. Cet utilitaire vérifie d'abord quels blocs sont utilisés sur un système de fichiers, puis les sauvegarde dans l'ordre du disque, éliminant la plupart des recherches.

Il existe un restoreutilitaire correspondant pour restaurer les sauvegardes créées par dump.

Il prend en charge les sauvegardes incrémentielles en utilisant les fichiers de sauvegarde de niveau 1 modifiés depuis la dernière sauvegarde (complète) de niveau 0, le niveau 2 modifié depuis la sauvegarde de niveau 1, etc.

Tometzky
la source
0

Pour les sauvegardes incrémentielles, une option serait d'avoir un deuxième arbre fantôme pour les nouvelles couvertures. Autrement dit, vous auriez votre arborescence principale qui est utilisée pour toutes les opérations de lecture. Vous auriez également un newfiles/012345.....jpgrépertoire; les couvertures nouvellement ajoutées créent un lien physique ici ainsi que dans l'arborescence principale. Lorsque vous effectuez des sauvegardes, vous pouvez parfois sauvegarder l'arborescence principale, mais sauvegarder l' newfilesarborescence (beaucoup plus petite) beaucoup plus régulièrement.

Notez que pour garder l' newfilesarborescence petite, avant d'effectuer une nouvelle sauvegarde de l'arborescence principale, vous pouvez vider l'arborescence newfiles:

mv newfiles newfiles_
mkdir newfiles
rm -rf newfiles_

Une fois que vous faites cela, bien sûr, vous vous engagez à produire une nouvelle sauvegarde de l'arborescence principale.

bdonlan
la source
Approche intéressante, merci de la partager. Mais je crains que cela n'implique de nombreux changements dans l'application, et il serait difficile de conserver l'application et les besoins de stockage dans deux couches distinctes.
Benjamin
0

L'ajout d'un peu de simultanéité est généralement utile.

J'ai un problème similaire à vous; dans mon cas, je dois sauvegarder environ 30 millions de fichiers, pour la plupart des fichiers HTML, PHP ou JPEG. Pour moi, BackupPC + rsync sur ssh fonctionne plutôt bien; la sauvegarde complète prend environ une journée, mais les incréments se terminent généralement en quelques heures.

L'astuce consiste à ajouter chaque répertoire de niveau principal (0, 1, 2 ... a, b, c ...) en tant que nouvelle cible à copier dans BackupPC et à le laisser effectuer la sauvegarde en parallèle, afin qu'il sauvegarde simultanément les répertoires a / , b / , c / * et ainsi de suite. Selon votre sous-système de disque, tout ce qui se situe entre deux processus et environ 10 processus est probablement le moyen le plus rapide de sauvegarder.

Les instantanés LVM et la sauvegarde au niveau bloc sont également une option, mais avec BackuPC et la sauvegarde au niveau fichier, vous pouvez toujours restaurer des fichiers ou des répertoires individuels si nécessaire.

Janne Pikkarainen
la source
Je suis surpris que la sauvegarde simultanée des répertoires racine résout le problème pour vous, je m'attendrais à ce que ce soit plus lent. Tous les répertoires sont-ils sur le même disque? Utilisez-vous un SSD?
Benjamin
Les fichiers de données sont stockés sur SAN.
Janne Pikkarainen
D'accord, cela a du sens maintenant, vous gagnez en efficacité en accédant à plusieurs fichiers simultanément, car vos différents dossiers sont très probablement physiquement situés sur différents lecteurs dans le SAN, ou au moins répliqués sur plusieurs lecteurs, ce qui permet un accès simultané. Je ne suis basé que sur un RAID-1, donc je suppose qu'au-dessus de deux accès simultanés, ma vitesse est très susceptible de baisser.
Benjamin
0

Benjoin,

Je pense que votre problème peut être résolu au nombre de fichiers par niveau de répertoire!

Le temps d'accès change-t-il de manière significative si vous stockez 20 000 fichiers dans un répertoire?

Avez-vous également pensé à stocker les métadonnées du système de fichiers sur un lecteur d'accès plus rapide séparé (comme un SSD).

Dragos
la source
0

Je recommanderais plutôt une bonne vieille base de données relationnelle.

J'utiliserais un PostgreSQL avec, disons, 256 tables partitionnées (cover_00, cover_01, ..., cover_ff) avec des données d'image comme byteacolonne (binaire) avec stockage externe, avec l'identifiant de fichier comme clé primaire. La récupération d'une image serait rapide (grâce à un index sur la clé primaire), l'intégrité des données serait garantie (base de données conforme ACID), la sauvegarde serait dans l'ordre du disque, donc pas trop de recherche.

Tometzky
la source