Linux 内存中Page cache和buffer cache 的区别

时间:2022-06-05 16:43:02

linux page buffer cache深入理解



Page cache和buffer cache一直以来是两个比较容易混淆的概念,在网上也有很多人在争辩和猜想这两个cache到底有什么区别,讨论到最后也一直没有一个统一和正确的结论,在我工作的这一段时间,page cache和buffer cache的概念曾经困扰过我,但是仔细分析一下,这两个概念实际上非常的清晰。如果能够了解到这两个cache的本质,那么我们在分析io问题的时候可能会更加得心应手。


Page cache实际上是针对文件系统的,是文件的缓存,在文件层面上的数据(在文件系统构架里,组成一个文件的有两部分:文件的元数据,即FCB,还有文件的业务数据,即比如平时我们用记事本程序打开一个文件所看到的数据。“在文件层面上的数据”指的就是文件的业务数据会缓存到page cache(即page cache规划就是用来缓存来自在文件系统下的任一文件的业务数据所存放的那些扇区))。文件的逻辑层需要映射到实际的物理磁盘,这种映射关系由文件系统来完成。当page cache的数据需要刷新时,page cache中的数据交给buffer cache,但是这种处理在2.6版本的内核之后就变的很简单了,没有真正意义上的cache操作(是说直接将文件的业务数据(以扇区为读写的基本单位方式,这个方式也是数据从磁盘读取到buffer cache上的方式)读取到page cache上,不经过buffer cache?)。


Buffer cache是针对磁盘块(即扇区)的缓存(即buffer cache允许缓存的数据可以是来自一个磁盘上任意一个扇区的数据),也就是在没有文件系统的情况下(准确的表达是,无论有否文件系统的存在,设备驱动程序读取的数据(也即直接对磁盘进行操作的数据)都是缓存到buffer cache中),直接对磁盘进行操作的数据会缓存到buffer cache中,例如,文件系统的元数据都会缓存到buffer cache中。

也就是说,首先我们要知道进程(0)(即设备驱动程序,或设备文件)对磁盘进行读写的基本单位是扇区(不是其他大小,如文件系统块大小),所以内存上(的是无论page cache,还是buffer cache)对磁盘进行读写的基本单位是扇区。进程(1)对Buffer cache进行读写的基本单位也是扇区,进程(2)对page cache进行读写的基本单位则是文件系统块。例如,buffer cache通过进程(0)(即设备驱动程序)从磁盘上取一些数据(这些数据可能分散开的,也可能连续一起,如果更巧的话,正好连续成一个文件系统块的大小)扇区为基本单位,接着page cache通过进程(1)(非设备驱动程序了,是一般的程序了)buffer cache将这些数据读取到自己上也扇区为基本单位的,之后,进程(2)(非设备驱动程序了,是一般的程序了)page cache将这些数据读取到自己上时则文件系统块为基本单位的 。 

Buffer cache算是属于硬盘分区这个层次的一部分,page cache 算是属于硬盘分区这个层次的上一层即文件系统这个层次的一部分 。文件系统对磁盘有一个自己的格式划分(即以文件系统块为划分单位),但是文件系统(的进程)不能直接去读写磁盘(即就不可能以文件系统块为单位来直接读写磁盘上的数据),文件系统(的进程)只能调用驱动程序去读写磁盘上的数据驱动程序直接读写磁盘上的数据是以扇区为基本单位的,而直接对磁盘进行操作的数据则是(程序编程时规划)缓存到buffer cache中。

简单说来,page cache用来缓存文件数据(即文件的业务数据),buffer cache用来缓存磁盘数据(例如,文件系统这个层次上,文件系统的元数据(比如,FAT文件系统中的文件分配表FAT就是属于文件系统的元数据),文件的元数据(即FCB,文件控制块(块,广义的概念是指一片存储区域,无关这片存储区域多大,即无关这片存储区域是否为如文件系统块或扇区的整数倍,小于它们或不是它们的整数倍都可以,像文件控制块就是128字节大小));在硬盘分区这个层次上,主引导记录(Master Boot Record,缩写:MBR),又叫做主引导扇区,分区表(DPT,Disk Partition Table))。在有文件系统的情况下,对文件操作,那么数据会缓存到page cache,如果直接采用dd等工具对磁盘进行读写,那么数据会缓存到buffer cache。 


更简单说来,

buffer cache允许缓存的数据可以是来自一个磁盘上任意一个扇区的数据,而page cache则规划就是用来缓存来自在文件系统下的任一文件的业务数据所存放的那些扇区。


补充一点,在文件系统层每个设备都会分配一个def_blk_ops的文件操作方法,这是设备的操作方法,在每个设备的inode下面会存在一个radix tree,这个radix tree下面将会放置缓存数据的page页。这个page的数量将会在top程序的buffer一栏中显示。如果设备做了文件系统,那么会生成一个inode,这个inode会分配ext3_ops之类的操作方法,这些方法是文件系统的方法,在这个inode下面同样存在一个radix tree,这里会缓存文件的page页,缓存页的数量在top程序的cache一栏进行统计。从上面的分析可以看出,2.6内核中的buffer cache和page cache在处理上是保持一致(即对两个cache上的数据的操作方法类似)的,但是存在概念上的差别(即操作或叫针对的对象不一样),page cache针对文件的cache,buffer是针对磁盘块数据的cache,仅此而已。








buffer 与cache 的区别
A buffer is something that has yet to be “written” to disk. A cache is something that has been “read” from the disk and stored for later use.
更详细的解释参考:Difference Between Buffer and Cache
对于共享内存(Shared memory),主要用于在UNIX 环境下不同进程之间共享数据,是进程间通信的一种方法,一般的应用程序不会申请使用共享内存,笔者也没有去验证共享内存对上面等式的影响。如果你有兴趣,请参考:What is Shared Memory?





cache 和 buffer的区别:
Cache:高速缓存,是位于CPU与主内存间的一种容量较小但速度很高的存储器。由于CPU的速度远高于主内存,CPU直接从内存中存取数据要等待一定时间周期,Cache中保存着CPU刚用过或循环使用的一部分数据,当CPU再次使用该部分数据时可从Cache中直接调用,这样就减少了CPU的等待时间,提高了系统的效率。Cache又分为一级Cache(L1 Cache)和二级Cache(L2 Cache),L1 Cache集成在CPU内部,L2 Cache早期一般是焊在主板上,现在也都集成在CPU内部,常见的容量有256KB或512KB L2 Cache.
Buffer:缓冲区,一个用于存储速度不同步的设备或优先级不同的设备之间传输数据的区域。通过缓冲区,可以使进程之间的相互等待变少,从而使从速度慢的设备读入数据时,速度快的设备的操作进程不发生间断。

Free中的buffer和cache:(它们都是占用内存):
buffer :作为buffer cache的内存,是块设备的读写缓冲区
cache(名词):作为page cache的内存, 文件系统的cache

如果 cache(名词) 的值很大,说明cache住的文件数很多。如果频繁访问到的文件都能被cache(动词)住,那么磁盘的读IO 必会非常小。


参考:

buffers cache 区别  谷歌

背景

Oracle中buffer cache里buffer和cache两个词的 区别