块和inode分配策略¶
ext4(无论如何,比ext3更好)认识到数据局部性通常是文件系统的一个理想特性。在旋转磁盘上,将相关块彼此靠近可以减少磁头致动器和磁盘为访问数据块而必须执行的移动量,从而加快磁盘I/O。在SSD上当然没有移动部件,但局部性可以增加每个传输请求的大小,同时减少请求的总数。这种局部性还可能导致写入集中在单个擦除块上,从而显著加快文件重写速度。因此,尽可能减少碎片是有益的。
ext4 用于对抗碎片的第一个工具是多块分配器。当文件首次创建时,块分配器会推测性地为文件分配 8KiB 的磁盘空间,假设该空间很快就会被写入。当文件关闭时,未使用的推测性分配当然会被释放,但如果推测正确(通常适用于小文件的完整写入),那么文件数据将以单个多块范围的形式写入。ext4 使用的第二个相关技巧是延迟分配。在这种方案下,当文件需要更多块来吸收文件写入时,文件系统会推迟决定磁盘上的确切位置,直到所有脏缓冲区都被写入磁盘。通过不到绝对必要时(达到提交超时,或调用 sync(),或内核内存不足时)才确定特定位置,希望文件系统能够做出更好的位置决策。
ext4(和ext3)使用的第三个技巧是,它试图将文件的数据块与其inode保存在同一个块组中。这减少了文件系统在首次读取文件的inode以了解文件数据块所在位置,然后寻址到文件数据块开始I/O操作时的寻道开销。
第四个技巧是,在可行的情况下,目录中的所有inode都与其目录本身放在同一个块组中。这里的工作假设是目录中的所有文件可能彼此相关,因此将它们放在一起是有用的。
第五个技巧是,磁盘卷被划分为128MB的块组;这些迷你容器如上所述用于尝试维护数据局部性。然而,存在一个刻意的怪异之处——当在根目录中创建目录时,inode分配器会扫描块组,并将该目录放入它能找到的负载最轻的块组中。这鼓励目录分散到整个磁盘上;当顶层目录/文件块填满一个块组时,分配器会简单地移到下一个块组。据称这种方案可以平衡块组的负载,尽管作者怀疑那些不幸地落在旋转驱动器末尾的目录在性能方面会受到不公平待遇。
当然,如果所有这些机制都失败了,人们总可以使用 e4defrag 来碎片整理文件。