写入子文件夹比写入其父文件夹更快

写入子文件夹比写入其父文件夹更快

我使用 dd 来测量写入性能,并观察到一些奇怪的现象:写入 /data/emzed2 比写入 /data 更快。这是我测量性能的方式:

$ dd if=/dev/zero= /数据/emzed2/测试文件BS=32

^C4921834+0 记录

4921834+0 条记录,复制 157498688 字节(157 MB),耗时 2,87329 秒,54,8 MB/秒

$ dd if=/dev/zero= /数据/测试文件BS=32

^C2487991+0 记录

2487991+0 条记录,复制 79615712 字节(80 MB),耗时 2,6501 秒,30,0 MB/秒

两个文件夹都位于 SSD 驱动器上的同一分区上。我使用 Ubuntu 14.04 并重复了几次实验,结果相似。

知道发生什么事了吗?

答案1

看来你受到了 ext4 优化的影响其中一些内容在Ext4 磁盘布局文档。

每次您增大文件大小(例如使用 dd),都会为新数据分配一些空间。最终,文件可能会出现碎片,即数据可能会分散在磁盘的多个块中。碎片是众所周知的导致速度变慢的原因(在读取和写入时),因此文件系统实现通常会尝试避免它。与 SSD 相比,旋转磁盘(磁头需要移动到连续的块)的碎片成本要高得多,但大多数文件系统实现都使用针对 SSD 的旋转磁盘优化策略。

上述文档中描述的第三、第四和第五个“技巧”的组合可能解释为什么在您的情况下写入子目录的速度更快。

第五个技巧是将磁盘卷分割成 128MB 块组。[…] 在根目录中创建目录时,inode 分配器会扫描块组并将该目录放入它能找到的负载最轻的块组中。

因此,emzed2可能是在 128MB 的空块中创建的。

第四个技巧是,如果可行的话,将目录中的所有 inode 放在与目录相同的块组中。

因此,/data/testfile是在(可能负载很重的)根块组中创建的,而是在(可能为空的)块组/data/emzed2/testfile中创建的。emzed2

第三个技巧 […] 是它尝试将文件的数据块保存在与其 inode 相同的块组中。

对于/data/emzed2/testfile,文件系统将首先分配emzed2块组中的所有数据块。如果此块最初为空,则对于前 128MB,这意味着根本没有碎片。对于/data/testfile,如果根块组尚未填满,文件系统将首先填充根块组,然后寻找其他地方来存储数据。

此外,您每次都会将文件增大 32 个字节。幸运的是,文件系统(例如 ext4)会分配比您请求的数据更多的数据(对于 ext4,以 8kb 为单位),并尝试延迟分配。您可能会看到类似的模式bs=8196,但块大小越大,速度差异可能会越小。

相关内容