Performances NTFS et grands volumes de fichiers et de répertoires

183

Comment Windows avec NTFS fonctionne-t-il avec de gros volumes de fichiers et de répertoires?

Existe-t-il des conseils sur les limites de fichiers ou de répertoires que vous pouvez placer dans un seul répertoire avant de rencontrer des problèmes de performances ou d'autres problèmes?

Par exemple, avoir un dossier contenant 100 000 dossiers à l'intérieur est-il une bonne chose à faire?

James Newton-King
la source
Les réponses à la question connexe sont inférieures à la réponse acceptée ici.
Eric J.29
Cette implémentation pourrait être utile: github.com/acrobit/AcroFS
Ghominejad

Réponses:

271

Voici quelques conseils de quelqu'un avec un environnement dans lequel nous avons des dossiers contenant des dizaines de millions de fichiers.

  1. Un dossier stocke les informations d'index (liens vers les fichiers enfants et le dossier enfant) dans un fichier d'index. Ce fichier deviendra très volumineux lorsque vous aurez beaucoup d'enfants. Notez que cela ne fait pas la distinction entre un enfant qui est un dossier et un enfant qui est un fichier. La seule différence est que le contenu de cet enfant est soit l'index du dossier de l'enfant, soit les données du fichier de l'enfant. Remarque: je simplifie quelque peu cela, mais cela fait passer le message.
  2. Le fichier d'index sera fragmenté. Lorsqu'il devient trop fragmenté, vous ne pourrez pas ajouter de fichiers à ce dossier. C'est parce qu'il y a une limite sur le nombre de fragments autorisés. C'est par conception. Je l'ai confirmé avec Microsoft lors d'un appel d'incident de support. Ainsi, bien que la limite théorique du nombre de fichiers que vous pouvez avoir dans un dossier soit de plusieurs milliards, bonne chance lorsque vous commencez à frapper des dizaines de millions de fichiers car vous atteindrez d'abord la limite de fragmentation.
  3. Ce n'est pas mal du tout cependant. Vous pouvez utiliser l'outil: contig.exe pour défragmenter cet index. Cela ne réduira pas la taille de l'index (qui peut atteindre plusieurs Go pour des dizaines de millions de fichiers) mais vous pouvez réduire le nombre de fragments. Remarque: L'outil de défragmentation de disque ne défragmentera PAS l'index du dossier. Il défragmentera les données du fichier. Seul l'outil contig.exe défragmentera l'index. Pour info: vous pouvez également l'utiliser pour défragmenter les données d'un fichier individuel.
  4. Si vous défragmentez, n'attendez pas d'avoir atteint le nombre maximum de fragments. J'ai un dossier dans lequel je ne peux pas défragmenter car j'ai attendu qu'il soit trop tard. Mon prochain test consiste à essayer de déplacer certains fichiers de ce dossier dans un autre dossier pour voir si je pourrais le défragmenter ensuite. Si cela échoue, alors ce que je devrais faire est 1) créer un nouveau dossier. 2) déplacez un lot de fichiers vers le nouveau dossier. 3) défragmentez le nouveau dossier. répétez # 2 & # 3 jusqu'à ce que cela soit fait, puis 4) supprimez l'ancien dossier et renommez le nouveau dossier pour qu'il corresponde à l'ancien.

Pour répondre plus directement à votre question: si vous recherchez 100 000 entrées, pas de souci. Allez vous assommer. Si vous regardez des dizaines de millions d'entrées, alors soit:

a) Prévoyez de les sous-diviser en sous-dossiers (par exemple, disons que vous avez 100 Mo de fichiers. Il est préférable de les stocker dans 1000 dossiers pour ne disposer que de 100 000 fichiers par dossier plutôt que de les stocker dans un seul grand dossier. créera 1000 index de dossier au lieu d'un seul gros qui est plus susceptible d'atteindre la limite du nombre maximum de fragments ou

b) Prévoyez d'exécuter régulièrement contig.exe pour que l'index de votre grand dossier reste défragmenté.

Lisez ci-dessous uniquement si vous vous ennuyez.

La limite réelle n'est pas sur le nombre de fragment, mais sur le nombre d'enregistrements du segment de données qui stocke les pointeurs vers le fragment.

Vous disposez donc d'un segment de données qui stocke des pointeurs vers les fragments des données de l'annuaire. Les données du répertoire stockent des informations sur les sous-répertoires et sous-fichiers que le répertoire est censé avoir stocké. En fait, un répertoire ne «stocke» rien. C'est juste une fonction de suivi et de présentation qui présente l'illusion de la hiérarchie à l'utilisateur puisque le support de stockage lui-même est linéaire.

MrB
la source
5
Où puis-je trouver plus d'informations sur contig.exe, ce n'est pas sur mon serveur. Une recherche Google a renvoyé cette page technet qui ne contient aucune mention de sous-répertoires ou de défragmentation d'index de dossier.
Evan Carroll
35
J'ai découvert la fragmentation de l'index des contig et des dossiers lors d'un appel technique avec un ingénieur Microsoft. C'était une énorme douleur dans le cul à travers leurs couches inutiles de support technique de niveau 1 à 3. (Euh ... avez-vous essayé d'exécuter chkdsk? Pouvez-vous essayer d'ouvrir le dossier dans l'Explorateur Windows? Pouvez-vous vérifier les autorisations du dossier?) FOOL! Je ne vais pas rester ici pendant 7 jours à attendre que votre putain de chkdsk scanne un lecteur contenant des dizaines de millions de fichiers !!
MrB
5
@ ss2k - Il suffit de pointer contig.exevers un répertoire, je pense que ça fera l'affaire: contig -a .donne:C:\temp\viele-Dateien is in 411 fragments Summary: Number of files processed : 1 Average fragmentation : 411 frags/file
Lumi
3
@GPhilo Je peux confirmer que les performances se dégradent toujours sur un SSD lors de l'utilisation de millions de fichiers. J'ai également essayé de défragmenter le dossier, mais contig n'y a rien fait. Il a agi comme s'il s'était terminé mais a montré la même fragmentation avant et après son exécution.
Bram Vanroy
1
En ce qui concerne l'exécution de Contig pour défragmenter l'index, dois-je exécuter contig sur c:\my\big\directory, ou c:\my\big\directory\*, ou sur $mft? (ou autre chose?)
Stephen R
47

Il existe également des problèmes de performances avec la création de noms de fichiers courts qui ralentissent les choses. Microsoft recommande de désactiver la création de nom de fichier court si vous avez plus de 300k fichiers dans un dossier [1]. Moins les 6 premiers caractères sont uniques, plus c'est un problème.

[1] Fonctionnement de NTFS sur http://technet.microsoft.com , recherchez "300 000"

Tony Lee
la source
3
Je voudrais ajouter une citation ici If you use large numbers of files in an NTFS folder (300,000 or more), disable short-file name generation for better performance, and especially if the first six characters of the long file names are similar.- épargne la recherche de l'indice "300 000". BTW: taper "300" sera suffisant (= pas besoin de presse-papiers ici)
Wolf
32

Je construis une structure de fichiers pour héberger jusqu'à 2 milliards (2 ^ 32) de fichiers et j'ai effectué les tests suivants qui montrent une forte baisse des performances de navigation + lecture à environ 250 fichiers ou 120 répertoires par répertoire NTFS sur un disque SSD ( SSD):

  • Les performances des fichiers diminuent de 50% entre 250 et 1000 fichiers.
  • Les performances de l'annuaire diminuent de 60% entre 120 et 1 000 annuaires.
  • Les valeurs pour les nombres> 1000 restent relativement stables

Fait intéressant, le nombre de répertoires et de fichiers n'interfère PAS de manière significative.

Les leçons sont donc:

  • Les numéros de fichier supérieurs à 250 coûtent un facteur de 2
  • Les répertoires supérieurs à 120 coûtent un facteur de 2,5
  • L'explorateur de fichiers de Windows 7 peut gérer de gros #Files ou #Dirs, mais la convivialité est toujours mauvaise.
  • L'introduction de sous-répertoires n'est pas chère

Voici les données (2 mesures pour chaque fichier et répertoire):

(FOPS = File Operations per Second)
(DOPS = Directory Operations per Second)

#Files  lg(#)   FOPS    FOPS2   DOPS    DOPS2
   10   1.00    16692   16692   16421   16312
  100   2.00    16425   15943   15738   16031
  120   2.08    15716   16024   15878   16122
  130   2.11    15883   16124   14328   14347
  160   2.20    15978   16184   11325   11128
  200   2.30    16364   16052   9866    9678
  210   2.32    16143   15977   9348    9547
  220   2.34    16290   15909   9094    9038
  230   2.36    16048   15930   9010    9094
  240   2.38    15096   15725   8654    9143
  250   2.40    15453   15548   8872    8472
  260   2.41    14454   15053   8577    8720
  300   2.48    12565   13245   8368    8361
  400   2.60    11159   11462   7671    7574
  500   2.70    10536   10560   7149    7331
 1000   3.00    9092    9509    6569    6693
 2000   3.30    8797    8810    6375    6292
10000   4.00    8084    8228    6210    6194
20000   4.30    8049    8343    5536    6100
50000   4.70    7468    7607    5364    5365

Et voici le code de test:

[TestCase(50000, false, Result = 50000)]
[TestCase(50000, true, Result = 50000)]
public static int TestDirPerformance(int numFilesInDir, bool testDirs) {
    var files = new List<string>();
    var dir = Path.GetTempPath() + "\\Sub\\" + Guid.NewGuid() + "\\";
    Directory.CreateDirectory(dir);
    Console.WriteLine("prepare...");
    const string FILE_NAME = "\\file.txt";
    for (int i = 0; i < numFilesInDir; i++) {
        string filename = dir + Guid.NewGuid();
        if (testDirs) {
            var dirName = filename + "D";
            Directory.CreateDirectory(dirName);
            using (File.Create(dirName + FILE_NAME)) { }
        } else {
            using (File.Create(filename)) { }
        }
        files.Add(filename);
    }
    //Adding 1000 Directories didn't change File Performance
    /*for (int i = 0; i < 1000; i++) {
        string filename = dir + Guid.NewGuid();
        Directory.CreateDirectory(filename + "D");
    }*/
    Console.WriteLine("measure...");
    var r = new Random();
    var sw = new Stopwatch();
    sw.Start();
    int len = 0;
    int count = 0;
    while (sw.ElapsedMilliseconds < 5000) {
        string filename = files[r.Next(files.Count)];
        string text = File.ReadAllText(testDirs ? filename + "D" + FILE_NAME : filename);
        len += text.Length;
        count++;
    }
    Console.WriteLine("{0} File Ops/sec ", count / 5);
    return numFilesInDir; 
}
Spoc
la source
2
Vous constatez une perte de performances après 2 ^ 8 fichiers car vous devez désactiver la génération de noms courts (génération de noms à 8 caractères). Voir technet.microsoft.com/en-us/library/cc781134(v=ws.10).aspx
Kyle Falconer
1
Salut, j'ai essayé d'utiliser cette ligne de commande: jeu de comportement fsutil.exe disable8dot3 1 Après un redémarrage, les résultats étaient en grande partie les mêmes pour moins de 10000 fichiers / répertoires. L'article dit que ce n'est important que pour les nombres plus élevés. Ce que j'ai vu cependant était une performance générale. dégradation probablement due au facteur de charge plus élevé sur mon SSD (il est maintenant rempli à 80% au lieu de 45%)
Spoc
très utile, merci. Les estimations de millions dites par d'autres utilisateurs sont loin de ces valeurs numériques.
Adrian Maire
2
Même après avoir désactivé la génération de noms 8.3, vous devez toujours supprimer les noms 8.3 existants, sinon il y aura peu d'amélioration à l'énumération des fichiers existants.
Stephen R
15

100 000 devrait être bien.

J'ai (de façon anecdotique) vu des gens avoir des problèmes avec des millions de fichiers et j'ai moi-même eu des problèmes avec Explorer, n'ayant tout simplement pas la moindre idée de la façon de compter au-delà de 60 000 fichiers, mais NTFS devrait être bon pour les volumes dont vous parlez.

Au cas où vous vous poseriez la question, le nombre maximum technique (et je l'espère théorique ) de fichiers est: 4 294 967 295

Oli
la source
5
Pour les non-initiés, ce grand nombre correspond à (2 ^ 32 - 1) fichiers.
meatspace
8

Pour l'accès local, un grand nombre de répertoires / fichiers ne semble pas être un problème. Cependant, si vous y accédez via un réseau, il y a un impact notable sur les performances après quelques centaines (en particulier lors d'un accès à partir de machines Vista (XP à Windows Server w / NTFS semblait fonctionner beaucoup plus rapidement à cet égard)).

Brian Knoblauch
la source
4
Êtes-vous sûr qu'il s'agit de NTFS (protocole de disque sur le serveur) et non de SMB (niveau réseau)?
MSalters
Non, je n'ai fait aucune recherche supplémentaire pour affiner la cause. Les seules informations dont je dispose sont celles détaillées ci-dessus.
Brian Knoblauch
2

Lorsque vous créez un dossier avec N entrées, vous créez une liste de N éléments au niveau du système de fichiers. Cette liste est une structure de données partagée à l'échelle du système. Si vous commencez ensuite à modifier cette liste en continu en ajoutant / supprimant des entrées, je m'attends au moins à un conflit de verrouillage sur les données partagées. Cette affirmation - en théorie - peut affecter négativement les performances.

Pour les scénarios en lecture seule, je ne peux imaginer aucune raison de dégradation des performances des répertoires avec un grand nombre d'entrées.

Constantin
la source
1

J'ai eu une réelle expérience avec environ 100 000 fichiers (chacun plusieurs Mo) sur NTFS dans un répertoire tout en copiant une bibliothèque en ligne.

Il faut environ 15 minutes pour ouvrir le répertoire avec Explorer ou 7-zip.

L'écriture d'une copie de site avec winhttracksera toujours bloquée après un certain temps. Il traitait également du répertoire, contenant environ 1 000 000 fichiers. Je pense que le pire, c'est que le MFT ne peut être parcouru que séquentiellement.

Ouvrir le même sous ext2fsd sur ext3 a donné presque le même timing. Le passage à reiserfs (et non à reiser4fs) peut probablement aider.

Essayer d'éviter cette situation est probablement le meilleur.

Pour vos propres programmes, l'utilisation de blobs sans fs pourrait être bénéfique. C'est ainsi que Facebook le fait pour stocker des photos.

Ximik
la source
Je ne sais pas d'où vient que "le MFT ne peut être parcouru que séquentiellement"? Le MFT contient un arbre B et est traversé comme un arbre B
phuclv