哪个目录层次结构是最好的/最快的?

我有一个很大的目录,我想重新组织最高性能(访问时间)的许多caching文件。

  • 2个2TB SATA III硬盘,软件RAID 1(镜像)
  • 操作系统:Ubuntu 12.04 LTS
  • 文件系统:ext4
  • 500 GB的数据
  • 大约16-17万个文件
  • 平均文件大小:30KB
  • 文件名是MD5散列

文件通过PHP / Perl脚本(随机)访问。 这些脚本会生成绝对path并读取文件。 没有目录列表:几乎只是fopen文件的绝对path。

当前目录层次结构为: cacheDir/d4/1d/d41d8cd98f00b204e9800998ecf8427e.dat所以一级子目录有256个(例如d4 ),二级子目录有256个(例子中为1d )。 平均每个二级目录大约有200-300个文件。

问题:当cacheDir存在Webstream量高峰和大量cacheDiriowait正在增长,减慢了系统速度,缓解了非常高的负载和明显的延迟。 只有在访问cacheDir中的文件时才会出现此高负载。 如果我访问其他目录/文件相同的频率,磁盘和系统正在做的很好。

我想知道如果改变caching目录结构会提高性能? 改为(例如): cacheDir/d/4/1/d/8/d41d8cd98f00b204e9800998ecf8427e.dat (16个子目录分别位于: cacheDir/d/4/1/d/8/d41d8cd98f00b204e9800998ecf8427e.dat级,平均15个文件)。

我知道简单的台式SATA III硬盘上的软件RAID 1不是一个速度怪物,但也许有一些优化文件系统的好方法?

请注意:

  • 文件系统启用了dir-index
  • 文件系统挂载noatime
  • 文件系统使用e2fsck -Df进行了优化

这听起来很愚蠢,但事实( 你的真相)是基准的结果。 在任何情况下,可能都有文件系统比其他文件系统更快,但最佳结构最可能取决于磁盘的速度特性,RAM的数量和caching效率。

如果您使用较深级别的较小目录,会发生什么情况? 需要读取较less的数据以查找目录条目,但可能(如果该目录的父项不再被caching)。 假设目录条目是50个字节。 对于300个文件的整个目录,这是15K。 在连续读取时,您的磁盘可能会提供150+ MiB / s。 因此,读取300个文件或600个文件之间的差异是0.1毫秒。 定位时间最好是4ms(如果不是SSD的话)。 即对于每个保存的目录查找,您可以读取至less12.000个文件的条目。 这使我认为你的目录是相当小的。 但是,也许所有的目录条目都在caching中(我不知道如何监视它,这很有趣),所以这个计算是不相关的。 也许这有助于在后台每隔几秒访问一次所有目录的脚本,这样它们都不会被抛出caching。

我认为问题不是文件索引节点的查找时间。 可能有很多进程尝试同时执行I / O操作。 如果这导致在几个步骤中读取文件,那么性能当然是死的。 文件碎片也是如此。 看看filefrag和你的caching文件。 看看blockdev --setra 。 您应该根据您的平均文件大小(或文件大小超过90%的大小)进行调整,并检查是否有任何影响。 我也发现(几年前)提示除了最上面的所有设备都将这个值设置为零:

 /dev/sdx -> ra=0 /dev/mdx -> ra=0 /dev/lvm/ -> ra=xxxx 

我不知道你有多less愿意做,但我可以想象,一个保险丝模块将帮助你的情况下(取决于文件大小和预读效率):这个模块将不得不确保文件被读入(在用户空间范围内)这些访问不会中断。 下一步将按照磁盘上的位置对文件访问进行sorting,也就是在文件级别上对内核(以及磁盘本身)在单个I / O操作中所做的操作进行sorting。 而不是有一个大的文件系统的目录,你可以创build更小的LV。 因此,您可以按名称对文件访问进行sorting,并按照磁盘区域进行访问。

如果你愿意改变你的硬件,那么这可能是有趣的: 把元数据放在SSD上 。 而且你应该尝试从你的caching磁盘上获得写访问权限。 这可能主要是日志文件。 它们通常并不重要,所以它可能有助于将它们放在具有很长的提交时间和data=writeback的文件系统上。

如果(某些)caching数据是静态的(并且不需要ACL),那么如果将其从ext4移动到squashfs(压缩的只读FS),则可以testing性能。 即使透明压缩(FUSE)内的ext4可能会帮助,如果问题是在几个步骤中读取文件。 文件系统(和磁盘内部)预读会得到更多的文件(如果它是可压缩的)。