Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/393.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java NTFS目录有100K个条目。如果分布在100个子目录上,性能会提高多少?_Java_Performance_Filesystems_Ntfs_Large Data Volumes - Fatal编程技术网

Java NTFS目录有100K个条目。如果分布在100个子目录上,性能会提高多少?

Java NTFS目录有100K个条目。如果分布在100个子目录上,性能会提高多少?,java,performance,filesystems,ntfs,large-data-volumes,Java,Performance,Filesystems,Ntfs,Large Data Volumes,上下文 我们有一个自制的文件系统支持的缓存库。我们目前在一次安装中存在性能问题,原因是条目数量太多(例如多达100000条)。问题是:我们将所有fs条目存储在一个“缓存目录”中。非常大的目录性能很差 我们正在考虑将这些条目分散到子目录上——就像git所做的那样,例如,100个子目录,每个目录大约有1000条条目 问题 我知道较小的目录大小将有助于文件系统访问 但“扩展到子目录”是否会加快遍历所有条目的速度,例如枚举/读取所有100000个条目?即,当我们从FS存储初始化/预热缓存时,我们需要遍历

上下文 我们有一个自制的文件系统支持的缓存库。我们目前在一次安装中存在性能问题,原因是条目数量太多(例如多达100000条)。问题是:我们将所有fs条目存储在一个“缓存目录”中。非常大的目录性能很差

我们正在考虑将这些条目分散到子目录上——就像git所做的那样,例如,100个子目录,每个目录大约有1000条条目

问题

我知道较小的目录大小将有助于文件系统访问

但“扩展到子目录”是否会加快遍历所有条目的速度,例如枚举/读取所有100000个条目?即,当我们从FS存储初始化/预热缓存时,我们需要遍历所有100000个条目(并删除旧条目)可能需要10分钟以上的时间

“传播数据”会减少“遍历时间”吗。此外,这种“遍历”实际上可以/确实删除过时的条目(例如,N天以前的条目)将“传播数据”改进删除时间

附加上下文 -NTFS -Windows系列操作系统(服务器2003、2008)

-Java J2ee应用程序

我/我们将非常感谢任何关于文件系统可伸缩性问题的培训

提前谢谢

意志


p、 我应该说我有自己的工具和能力来测试这一点,但我想我会首先选择蜂巢思维作为理论和经验。

如果你永远不需要统计或列出缓存目录,并且只需要按完整路径统计和打开其中的文件,这应该并不重要(至少在100k文件级别)目录中有多少个文件

在这种情况下,许多缓存框架和文件系统密集型存储引擎将基于文件名中的第一个字符创建子目录,因此,如果在缓存中存储文件“abcdefgh.png”,它将进入“cache/a/b/cdefgh.png”,而不仅仅是“cache/abcdefgh.png”。这假设文件名的前两个字母在整个字符空间中的分布大致相同


正如您所提到的,由于您列出或遍历目录的主要任务是删除过时的文件,因此我建议您根据文件缓存的日期和/或时间创建目录,即“cache/2010/12/04/22/abcdefgh.png”,并且无论您在何处对缓存进行索引,请确保按文件名和日期对其进行索引(尤其是在数据库中)这样,您就可以按日期从索引中快速删除项并删除相应的目录。

您如何加载缓存?如果您使用标准Java文件系统交互,这将是您的第一个瓶颈-Java在文件夹内容迭代中非常糟糕-如果您在迭代时对每个文件进行检查(获取修改的日期,确保文件不是目录,等等。)性能可能会受到很大影响(这些都涉及到到到本地的往返行程)。转向基于本地FindFirstFile的解决方案可能会带来重大影响(如数量级)improvement.FindFirstFile返回每个迭代步骤中有关文件的所有信息。Java file.listFiles()返回路径列表。然后,当您查询属性或其他元时,每个调用都是到文件系统的往返。效率非常非常低

好的-那是不可能的。接下来,NTFS中大型目录的原始迭代并不比n元树方法(文件夹和子文件夹等)慢.对于FAT32,这是一个非常大的问题-但NTFS处理这类事情非常好。也就是说,拆分成子文件夹会带来一些自然的并行机会,而单文件夹很难实现这些机会。如果您可以生成10或15个线程,每个线程都访问单独的文件夹,那么您就可以有效地消除磁盘延迟y是一个促成因素


我可能会建议您从分析开始(当然,您已经知道了这一点),看看大部分加载时间是从哪里来的。您可能会感到惊讶(例如,在我们的一个进行大量文件列表处理的应用程序中,当检查isDirectory()时,我惊讶地发现我们被占用了多少时间)-一个简单的更改,比如在确定目录/文件之前进行日期比较,使我们的迭代速度提高了30%。

我还认为,将文件分散到子目录将加快操作

因此,我进行了测试:我生成了从AAAA到ZZZ的文件(26^4个文件,大约450K),并将它们放在一个NTFS目录中。我还将相同的文件放在从AA到ZZ的子目录中(即按文件名的前两个字母分组文件)。然后我执行了一些测试-枚举和随机访问。我在创建后和测试之间重新启动了系统

平面结构显示的性能比子目录稍好一些。我相信这是因为目录是缓存的,NTFS索引目录内容,所以查找速度很快

请注意,对于400K文件,完全枚举(在这两种情况下)大约需要3分钟。这是一段相当长的时间,但子目录会让情况更糟

结论:特别是在NTFS上,如果可以访问其中任何一个文件,那么将文件分组到子目录是没有意义的。如果您有缓存,我还将测试按日期或域对文件进行分组,假设某些文件的访问频率高于其他文件,并且操作系统不需要将所有目录保留在内存中。但是,对于您的文件数量(低于100K),这可能也不会带来显著的好处。我认为,您需要自己测量这些特定的场景

更新:我减少了随机访问的测试,只访问了一半的文件(从AA到OO)。假设这将涉及一个平面目录和一半的子目录