Cache 与 Buffer 之间的异同

在前文 阿里云服务器 MySQL 经常自动停止、挂掉并重启的解决方式 中监控 Linux 资源时,输入 top 命令后,发现内存相关 Mem 和 Swap 的 Buffer 和 Cache,觉得有必要深入了解下,故此对其做个小结。


free 命令相对于 top 命令能更为简洁的查看系统内存使用情况:

Mem:表示物理内存统计

-/+ buffers/cached:表示物理内存的缓存统计

Swap:表示硬盘上交换分区的使用情况,此处暂不赘述

系统的总物理内存:994M,但系统当前真正可用的内存并不是第一行 free 标记的 65M,它仅代表未被分配的内存。

简而言之,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-cache-and-buffer


利用 top 命令和 free 命令了解大致的情况后,下面就其区别进行具体描述:

Cache:高速缓存,是位于 CPU 与 主内存间的一种容量较小但速度很高的存储器。由于 CPU 的速度远高于主内存,CPU 直接从内存存取数据要等待一定时间周期。Cache 中保存着 CPU 刚用过或循环使用的一部分数据,当 CPU 再次使用该部分数据时可从 Cache 中直接调用,这样就减少了 CPU 的等待时间,提高了系统的效率。Cache又分为一级Cache(L1 Cache)和二级Cache(L2 Cache),L1 Cache集成在 CPU 内部,L2 Cache 早期一般是焊在主板上,现在也都集成在 CPU 内部,常见容量有 256KB或 512KB。

Buffer:I/O缓冲,一个用于存储速度不同步的设备或优先级不同的设备之间传输数据的区域。通过缓冲区,可以使进程之间的相互等待变少,从而提高内存和硬盘(或其他 I/O 设备)之间的数据交换。例如:从内存中将数据往硬盘中写入,并不是直接写入,而是缓冲到一定大小后刷入硬盘中。

共性:

都属于内存,数据都是临时的,一旦关机数据都会丢失。

差异:

A、buffer 是要写入数据;cache 是已读取数据。

B、buffer数据丢失会影响数据完整性,源数据不受影响;cache数据丢失不会影响数据完整性,但会影响性能。

C、一般来说 cache 越大,性能越好,超过一定程度,导致命中率太低后才会越大性能越低。对 buffer 而言,空间越大性能影响不大,够用就行。cache 过小,或者没有cache,不影响程序逻辑(高并发 cache过小或者丢失导致系统忙死除外)。buffer 过小有时会影响程序逻辑,如导致网络丢包。

D、cache 可以做到应用透明,编写应用的可以不用管是否有cache,可以在应用做好之后再上cache。当然开发者显式使用cache也行。buffer 需要编写应用的人设计,是程序的一部分。


Free 中的 buffer 和 cache(它们都占用内存):

buffer:作为 buffer cache 的内存,是块设备的读写缓冲区

cache:作为 page cache 的内存,文件系统的cache

Page cache 和 buffer cache 一直都是比较容易混淆的概念。关于两者之间的区别,各种争论一直都存在,实际上从本质上分析可知:

Page cache 是针对文件系统的,是文件的缓存,在文件层面上的数据会缓存到 page cache。文件的逻辑层需要映射到实际的物理磁盘,这种映射关系由文件系统来完成。当 page cache 的数据需要刷新时,page cache 中的数据交给 buffer cache,但是这种处理在 2.6 版本的内核之后就变得很简单了,没有真正意义上的cache操作。

Buffer cache 是针对磁盘块的缓存,即在没有文件系统的情况下,直接采用dd等工具对磁盘进行操作的数据会缓存到 buffer cache 中,例如,文件系统的元数据都会缓存到 buffer 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 在处理上是保持一致的,但是在概念上存在差别,page cache针对文件的cache,buffer是针对磁盘块数据的cache,仅此而已。

现在不都是只有 page cache 了吗?buffer pages 其实也是page cache里面的页。只是多了一层抽象,通过 buffer_head来进行一些访问管理。从 Linux 算法实现的角度,page cache 和 buffer cache 目前是一样的,但是从功能抽象和具体应用来讲,这两者还是存在区别的,这一点可以从本文开头 top 命令统计的信息中看出来。

发表评论

电子邮件地址不会被公开。 必填项已用*标注