与存取(真正的)内存相比,从磁盘读是很慢的 另外,在相对短的一端时间里,多次读硬盘相同的部分是很常见的。 例如,你可能先读了一封电子邮件,然后回复时又将它读入编辑器,然后复制它到一个文件夹时又用邮件程序读它。 或者,考虑命令ls 可能被系统上的很多用户多么频繁地使用。 只从磁盘读一次信息,并保持在硬盘中,知道不再需要,除了第一次读,其他都会较快。 这就叫磁盘缓存disk buffering,用于此目的的内存叫buffer cache。
不幸的是,由于内存是有限且缺乏的资源,buffer cache一般不会足够大(大到能够装下所有人可能用到的数据)。 当cache满时,最长时间不用的数据将被丢弃,内存释放给最新的数据。
磁盘缓冲也用于写操作。要写的数据经常马上又被读(例如一个源代码文件保存到文件中后又被编译器读出),所以 将要写的数据放在缓冲里是个好主意。另外,只将数据放如cache而不马上写到磁盘,写操作的程序执行速度更快。 写操作然后可以在后台完成,而不降低其他程序的速度。
许多操作系统有buffer caches (即使名称不同),但并非都根据上述原理。 有些是透写write-through: 数据马上写到磁盘(当然也同时写到cache) 不马上写的cache叫回写write-back。回写比透写更有效,但也更容易出错:如果系统崩溃,或电源突然掉电, 或软盘在cache回写前被取出,那么cache中改变的数据将丢失。这可能意味着文件系统is not in full working order, 可能由于未写数据包含了系统记录信息的重要的变化。
因此,千万不要不经过正常的关闭过程直接关闭电源(见6章), 或没有unmount就取出软盘(如果是mount的),或什么程序还在用着软盘,或软盘灯还在闪。 sync 命令刷新缓冲,即强制将所有未写数据写回磁盘,如果要确保所有 数据安全回写,可以用它。 传统的UNIX系统中,有个update 程序在后台运行,它每30秒运行一次 sync ,所以通常无须使用sync 。 Linux有一个另外的守侯程序bdflush ,它克服了sync 有时因磁盘I/O负荷太重(因为频繁的操作)而导致有时系统突然呆住的问题。
Linux下,bdflush 由update 启动。 一般无须考虑它,但如果bdflush 偶尔因为什么原因死了,核心会给出警告, 此时应该手工启动它(/sbin/update )。
cache并不真正缓冲文件,而是块,就是磁盘I/O的最小单元(Linux下,一般是1kB)。 这样,所有的目录、超级块、其他文件系统记录数据和无文件系统磁盘都可以被缓冲。
cache的效果决定于其大小。太小的cache几乎无用;它只能cache很少的数据,而可能在被重用前就被清除了。 大小有赖于有多少数据被读写,相同的数据的存取频度。唯一的方法是实验。
如果cache是固定大小,那么不应该太大,否则,会由于空闲内存空间太小而使用swap(也很慢)。 为了最有效地使用真实内存,Linux自动使用所有空闲内存作为buffer cache,当程序需要更多内存时, 自动减少cache。
Linux下,对cache使用无须做任何工作,它完全是自动的。除了要正常关闭系统和取出软盘,无须关心cache。