持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第8天,点击查看活动详情
快速文件系统
Fast File System快速文件系统是早期UNIX文件系统的改进版,早期的UNIX文件系统十分简单,如下图所示
问题是,性能很糟糕,到后面这个文件甚至不能提供磁盘总带宽的2%,而且用久了空间碎片化很严重,因此浪费很多磁盘空间。本质上,这个文件系统只是把磁盘当作一个随机访问的内存,在磁盘的使用过程中,空间的清理和分配都不是连续的,索引在空间中乱转,因此性能十分的差。如下图所示。
从现在的眼光来看,这种碎片化的问题能够通过磁盘碎片整理工具来重新组织数据,但是在当时来说这种开销是不可接收的。另一个问题是一个快太小,小的块对碎片化的问题有好处,但是对传输来说会线性的增大开销,这些问题导致这种文件系统难以使用。
伯克利的一个小组决定建立一个更好、更快的文件系统,他们称之为快速文件系统(FFS)。从此开启了文件系统研究的新时代,FFS的第一个特点就是保留文件系统的相同接口(相同的api,包括open()、read()、write()、close()和其他文件系统调用),但是在内部实现上大大改进。这种开发模式沿用至今,实际上,所有现代文件系统都遵循现有的接口(从而保持与应用程序的兼容性),同时出于性能、可靠性或其他原因更改其内部结构。
第一步就是更改磁盘上的结构,重新定义磁盘结构为一组cylinder,一个cylinder是不同盘片上平行的一条轨道。下图中,一共有3条cylinder。
但是这种结构并不是易用的,磁盘导出一共基于块的逻辑地址空间,并从客户端隐藏其几何结构。具体的,将逻辑地址空间相对应的分组,一组上的逻辑地址空间由一组cylinder上平行的物理空间组成,每一个组内都有一个和普通文件系统一样的数据结构,如下图所示
这样分组的意义在于分配文件和目录空间,事实上,分配只有一个原则:把相关的东西放在一起,这里我们用一些简单的启发式方法来定义什么东西是相关的,对于目录数据,找到已分配目录比较少、空间比较大的组(方便组间平衡目录),全部放进去,对于文件数据,首先是放到对应的inode附近,其次是相同目录的文件放到同一组里面。如下图所示
上图左边是按关联原则分配的空间,右边则没有,可以看出右边的存放方式使基于名称的局部性消失了。而左边因为具有局部性,使得相关文件的索引很快。
启发式方法:人在解决问题时所采取的一种根据经验规则进行发现的方法。其特点是在解决问题时,利用过去的经验,选择已经行之有效的方法,而不是系统地、以确定的步骤去寻求答案。
名称局部性,如下图所示基于名称的局部性的优势可以体现
对于大文件要特殊处理,不然可能会占满整个组,破坏局部性,如下图左侧所示,没有多少剩余空间给其它文件了。解决的方式也很简单如右图所示。
有人可能会注意到这种分散的存储方式会降低性能,因为需要在不同的组上来回切换。解决方案是增大块大小,因为假如块足够大,文件分散的组就少,这种方式也称为摊销(amortization),文件系统将会花费大量时间在磁盘传输上而不是搜索磁道。也就是说,峰值性能越高,所需的块大小越大,如下图所示。
FFS还有一些其它特性,比如极小块,因为大部分文件是很小的,为了减少内部碎片,引入小块的概念,这些小块都用于存储小文件,一块可能只有256KB或者512KB。另一个是磁盘布局,如下图所示,FFS将首先向0块发出读取;当读取完成时,FFS发出对block 1的读取,已经太晚了,block 1已经在头部下旋转,现在读取block 1将会引起一个完整的旋转。因此FFS采取右边的磁盘布局来解决这一问题,
但是如果是连续读取的话只能发挥峰值性能的50%(要转两圈),幸运的是,现代磁盘要聪明得多:它们内部读取整个磁道,并将其缓冲到内部磁盘缓存中(由于这个原因,通常称为磁道缓冲区)。然后,在对磁道进行后续读取时,磁盘将从其缓存中返回所需的数据。
还有一些其它的特性,如长文件名、符号链接、原子重命名等,这些特性使得FFS不仅性能更强而且更加可用。