带有 NTFS 的 Windows 如何处理大量文件和目录?
在遇到性能问题或其他问题之前,是否有关于可以放置在单个目录中的文件或目录限制的任何指导?
例如,有一个包含 100,000 个文件夹的文件夹是否可行?
带有 NTFS 的 Windows 如何处理大量文件和目录?
在遇到性能问题或其他问题之前,是否有关于可以放置在单个目录中的文件或目录限制的任何指导?
例如,有一个包含 100,000 个文件夹的文件夹是否可行?
这里有一些来自环境中的人的一些建议,我们有包含数千万个文件的文件夹。
更直接地回答您的问题:如果您正在查看 100K 条目,请不要担心。去把自己打晕。如果您正在查看数以千万计的条目,那么:
a) 制定计划将它们细分为子文件夹(例如,假设您有 100M 个文件。最好将它们存储在 1000 个文件夹中,这样每个文件夹只有 100,000 个文件,而不是将它们存储在 1 个大文件夹中。这将创建 1000 个文件夹索引,而不是一个更有可能达到最大片段数限制的大索引或
b) 制定计划定期运行 contig.exe 以保持大文件夹的索引碎片整理。
仅当您感到无聊时阅读以下内容。
实际限制不是片段的数量,而是存储指向片段的指针的数据段的记录数。
所以你所拥有的是一个数据段,它存储指向目录数据片段的指针。目录数据存储有关该目录应该存储的子目录和子文件的信息。实际上,目录不会“存储”任何东西。由于存储介质本身是线性的,因此它只是一种跟踪和呈现功能,向用户呈现层次结构的错觉。
短文件名的创建也存在性能问题,这会减慢速度。如果文件夹中的文件超过 300k,Microsoft 建议关闭短文件名创建 [1]。前 6 个字符的唯一性越少,问题就越大。
[1] NTFS 工作原理来自http://technet.microsoft.com,搜索“300,000”
我正在构建一个文件结构来托管多达 20 亿 (2^32) 个文件并执行以下测试,这些测试显示在固态驱动器上每个 NTFS 目录大约 250 个文件或 120 个目录时,导航 + 读取性能急剧下降(固态硬盘):
有趣的是,目录和文件的数量并没有显着干扰。
所以教训是:
这是数据(每个文件和目录的 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;
}
10万应该没问题。
我(轶事)看到人们遇到数百万个文件的问题,我自己也遇到过资源管理器的问题,只是不知道如何计算过去 60 到千个文件,但 NTFS 应该适合您所说的卷。
如果您想知道,技术(我希望是理论上的)最大文件数是:4,294,967,295
对于本地访问,大量目录/文件似乎不是问题。但是,如果您通过网络访问它,几百次之后性能就会明显下降(尤其是从 Vista 机器访问时(XP 到 Windows Server w/NTFS 在这方面似乎运行得更快))。
当您创建一个包含 N 个条目的文件夹时,您会在文件系统级别创建一个包含 N 个项目的列表。此列表是系统范围的共享数据结构。如果您随后开始通过添加/删除条目来不断地修改此列表,我预计至少会有一些共享数据的锁争用。这种争论 - 从理论上讲- 会对性能产生负面影响。
对于只读场景,我无法想象具有大量条目的目录性能下降的任何原因。
在复制一个在线库时,我在一个目录中的 NTFS 上拥有大约 100 000 个文件(每个文件数 MB)的真实经验。
使用 Explorer 或 7-zip 打开目录大约需要 15 分钟。
一段时间后,编写站点副本winhttrack
总是会卡住。它还处理目录,包含大约 1 000 000 个文件。我认为最糟糕的是 MFT 只能通过顺序遍历。
在 ext3 上的 ext2fsd 下打开相同的时间几乎相同。可能迁移到 reiserfs(不是 reiser4fs)会有所帮助。
尽量避免这种情况可能是最好的。
对于您自己的程序,使用不带任何 fs 的 blob 可能是有益的。这就是 Facebook 存储照片的方式。