【问题标题】:NTFS performance and large volumes of files and directoriesNTFS 性能和大量文件和目录
【发布时间】:2023-03-03 01:56:01
【问题描述】:

带有 NTFS 的 Windows 如何处理大量文件和目录?

在遇到性能问题或其他问题之前,是否有关于可以放置在单个目录中的文件或目录限制的任何指导?

例如拥有一个包含 100,000 个文件夹的文件夹是否可行?

【问题讨论】:

标签: windows performance filesystems ntfs


【解决方案1】:

以下是有人在我们拥有包含数千万个文件的文件夹的环境中提供的一些建议。

  1. 文件夹将索引信息(指向子文件和子文件夹的链接)存储在索引文件中。当你有很多孩子时,这个文件会变得非常大。请注意,它不区分作为文件夹的子对象和作为文件的子对象。唯一的区别实际上是该孩子的内容是孩子的文件夹索引或孩子的文件数据。注意:我在某种程度上简化了这一点,但这说明了重点。
  2. 索引文件将被分割。当它变得过于碎片化时,您将无法将文件添加到该文件夹​​。这是因为允许的片段数有限制。这是设计使然。我已在支持事件电话中与 Microsoft 确认了这一点。因此,尽管理论上一个文件夹中可以拥有的文件数量限制为数十亿,但当您开始达到数千万文件时,祝您好运,因为您将首先达到碎片限制。
  3. 但这并不全是坏事。您可以使用该工具:contig.exe 对该索引进行碎片整理。它不会减少索引的大小(对于数千万个文件,它可以达到几个 Gig),但您可以减少片段的数量。注意:磁盘碎片整理工具不会对文件夹的索引进行碎片整理。它将对文件数据进行碎片整理。只有 contig.exe 工具会对索引进行碎片整理。仅供参考:您也可以使用它对单个文件的数据进行碎片整理。
  4. 如果您进行碎片整理,请不要等到达到最大片段数限制。我有一个文件夹无法进行碎片整理,因为我等到为时已晚。我的下一个测试是尝试将该文件夹中的一些文件移到另一个文件夹中,看看我是否可以对其进行碎片整理。如果这失败了,那么我要做的是 1)创建一个新文件夹。 2)将一批文件移动到新文件夹。 3)对新文件夹进行碎片整理。重复 #2 和 #3 直到完成,然后 4) 删除旧文件夹并重命名新文件夹以匹配旧文件夹。

更直接地回答您的问题:如果您正在查看 100K 条目,请不要担心。去把自己打晕。如果您正在查看数以千万计的条目,那么:

a) 计划将它们细分为子文件夹(例如,假设您有 1 亿个文件。最好将它们存储在 1000 个文件夹中,这样每个文件夹只有 100,000 个文件,而不是将它们存储到 1 个大文件夹中)文件夹。这将创建 1000 个文件夹索引,而不是一个更有可能达到最大片段数限制或

b) 制定计划定期运行 contig.exe,以对大文件夹的索引进行碎片整理。

只有在您感到无聊时才阅读以下内容。

实际限制不是片段的数量,而是存储指向片段的指针的数据段的记录数。

所以你有一个数据段,它存储指向目录数据片段的指针。目录数据存储有关该目录应该存储的子目录和子文件的信息。实际上,目录不会“存储”任何东西。由于存储介质本身是线性的,因此它只是一种跟踪和呈现功能,向用户呈现层次结构的错觉。

【讨论】:

  • 在哪里可以找到有关contig.exe 的更多信息,它不在我的服务器上。 Google 搜索返回了 this technet page,其中没有提及子目录或文件夹索引碎片整理。
  • 我在与 Microsoft 工程师的技术电话中发现了 contig 和文件夹索引碎片。经历他们无用的 1-3 层技术支持是一个巨大的痛苦。 (呃……你试过运行 chkdsk 吗?你能试着在 Windows 资源管理器中打开文件夹吗?你能检查文件夹权限吗?) 傻瓜!我不会坐在这里 7 天等待你该死的 chkdsk 扫描包含数千万文件的驱动器!
  • @ss2k - 只需将contig.exe 指向一个目录,我认为就可以完成这项工作:contig -a . 给出:C:\temp\viele-Dateien is in 411 fragments Summary: Number of files processed : 1 Average fragmentation : 411 frags/file
  • 这仍然是 SSD 磁盘的问题吗?我必须制作一个包含大量快捷方式的文件夹(大约 6 mils)。我在另一个较小的文件夹上尝试了 contig.exe,我确实看到它非常碎片化(1075 个碎片),但 contig 不会对其进行碎片整理。
  • @GPhilo 我可以确认在使用数百万个文件时,SSD 的性能仍然会下降。我也尝试对文件夹进行碎片整理,但 contig 没有对它做任何事情。它表现得好像它完成了,但在运行之前和之后显示出相同的碎片。
【解决方案2】:

短文件名的创建也存在性能问题,这会减慢速度。如果文件夹中的文件超过 300k,Microsoft 建议关闭短文件名创建 [1]。前 6 个字符的唯一性越少,问题就越大。

[1] How NTFS Works 来自http://technet.microsoft.com,搜索“300,000”

【讨论】:

  • 我会在此处添加引用 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. - 无需搜索“300,000”提示。顺便说一句:输入“300”就足够了(= 这里不需要剪贴板)
【解决方案3】:

我正在构建一个文件结构来托管多达 20 亿 (2^32) 个文件,并执行了以下测试,这些测试显示在实体上每个 NTFS 目录大约 250 个文件或 120 个目录时,导航 + 读取性能急剧下降状态驱动器 (SSD):

  • 文件性能在 250 到 1000 个文件之间下降 50%。
  • 目录性能在 120 到 1000 个目录之间下降 60%。
  • 数字 > 1000 的值保持相对稳定

有趣的是,目录和文件的数量并没有显着干扰。

所以教训是:

  • 大于 250 的文件号的成本是 2 倍
  • 120 以上的目录成本是 2.5 倍
  • Windows 7 中的 File-Explorer 可以处理较大的 #Files 或 #Dirs,但可用性仍然很差。
  • 引入子目录并不昂贵

这是数据(每个文件和目录 2 个测量值):

(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

这是测试代码:

[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; 
}

【讨论】:

  • 您会在 2^8 个文件后看到性能损失,因为您需要禁用短名称生成(8 个字符的名称生成)。见technet.microsoft.com/en-us/library/cc781134(v=ws.10).aspx
  • 嗨,我试过使用这个命令行: fsutil.exe behavior set disable8dot3 1 重新启动后,对于少于 10000 个文件/目录,结果基本相同。文章说它只对更高的数字很重要。我看到的是一般性能。性能下降可能是由于我的 SSD 上的负载系数较高(现在是 80% 而不是 45%)
  • 即使在禁用 8.3 名称生成之后,您仍然需要剥离现有的 8.3 名称,否则对现有文件的枚举几乎没有改进。
  • NTFS 将目录存储为 B 树。那些你看到性能急剧变化的点仅仅是当 B 树由于增长而变得更深一层时。这些点可能因文件名长度而异(因为 NTFS 尝试在每个 4K B 树节点中尽可能多地容纳空间允许的条目,并且文件名长度决定了每个条目的大小),以及是否启用了短名称(因为这样 NTFS 可能必须为每个文件添加两个条目,而不仅仅是一个)。
【解决方案4】:

100,000 应该没问题。

我(传闻)看到人们在处理数百万个文件时遇到问题,我自己也遇到过资源管理器问题,只是不知道如何计算过去 60 到千个文件,但 NTFS 应该对您的卷有好处'再谈。

如果您想知道,技术(我希望理论上)最大文件数是:4,294,967,295

【讨论】:

  • 对于外行来说,这个大数字是 (2^32 - 1 ) 个文件。
【解决方案5】:

对于本地访问,大量目录/文件似乎不是问题。但是,如果您通过网络访问它,几百次之后性能就会明显下降(尤其是从 Vista 机器访问时(XP 到 Windows Server w/NTFS 在这方面似乎运行得更快)。

【讨论】:

  • 您确定这是 NTFS(服务器上的磁盘协议),而不是 SMB(网络级别)吗?
  • 不,我没有做进一步的研究来缩小原因。我拥有的唯一信息如上所述。
【解决方案6】:

当您创建一个包含 N 个条目的文件夹时,您会在文件系统级别创建一个包含 N 个项目的列表。此列表是系统范围的共享数据结构。如果您随后开始通过添加/删除条目来不断地修改此列表,我预计至少会有一些共享数据的锁争用。这种争用 - 理论上 - 会对性能产生负面影响。

对于只读方案,我无法想象具有大量条目的目录性能下降的任何原因。

【讨论】:

    【解决方案7】:

    在复制一个在线图书馆时,我在 NTFS 上的目录中拥有大约 100 000 个文件(每个数 MB)的真实经验。

    使用 Explorer 或 7-zip 打开目录大约需要 15 分钟。

    使用winhttrack 编写站点副本总是会在一段时间后卡住。它还处理目录,包含大约 1 000 000 个文件。我认为最糟糕的是MFT只能通过顺序遍历。

    在 ext3 上的 ext2fsd 下打开相同的文件给出了几乎相同的时间。 迁移到 reiserfs(不是 reiser4fs)可能会有所帮助。

    尽量避免这种情况可能是最好的。

    对于您自己的程序,使用不带任何 fs 的 blob 可能是有益的。 这就是 Facebook 存储照片的方式。

    【讨论】:

    • 我不确定你从哪里得到“MFT 只能通过顺序遍历”? MFT 包含一个 B-tree 并且像 B-tree 一样被遍历
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-19
    • 2011-01-02
    • 2011-01-18
    相关资源
    最近更新 更多