理解 Linux 内存中的缓冲区(Buffer)和缓存(Cache)
今天这篇文章分享下 Linux 内存中的缓冲区(Buffer)和缓存(Cache)这两个关键概念。Buffer 是一种临时存储区域,主要用于处理输入输出(I/O)操作。它的设计目的是为了应对设备之间的速度差异,尤其是在 CPU 和外部设备(如硬盘)的读写速度不匹配时。当应用程序需要进行 I/O 操作时,例如读取文件或写入数据,数据会首先被放置在 buffer 中。这个过程的典型步骤如下:1. 数据传输:当应用程序请求读取文件时,操作系统会将数据从磁盘读取到 buffer 中,而不是直接将数据传递给应用程序。这种方式可以减少直接 I/O 操作的数量,提高效率。2. 异步处理:应用程序可以继续执行其他任务,而不必等待数据从磁盘完全读取。操作系统会在后台处理 buffer 中的数据,确保数据的完整性。3. 减少磨损:通过使用 buffer,系统可以减少对硬盘等物理设备的频繁访问,从而降低设备的磨损。- 文件读取与写入:在文件系统中,buffer 用于临时存储正在读取或写入的数据,以提高 I/O 性能。
- 网络数据传输:在网络编程中,buffer 用于存储网络数据包,以确保数据的顺序和完整性。
Cache 是一种高速存储区域,用于存储最近访问的数据或计算结果,旨在提高数据访问速度。与 buffer 不同,cache 更加关注性能优化。1. 数据存储:当应用程序访问某个文件或数据时,操作系统会将该数据存储在 cache 中。下次请求相同的数据时,系统会直接从 cache 中返回,而无需再次访问磁盘。2. 智能管理:为了有效利用缓存,操作系统通常采用一些算法来决定哪些数据应保留在 cache 中,哪些数据应该被替换。这种管理方式确保最常用的数据能够快速访问。3. 提高性能:由于 cache 存储在内存中,其访问速度远快于从硬盘读取数据,因此能够显著提高系统的响应速度和性能。- 文件系统缓存:Linux 会将常用的文件、目录结构等存储在内存中,以加快后续的访问速度。
- CPU 缓存:现代处理器通常会有多级缓存(L1、L2、L3),用于存储指令和数据,以减少访问主存的延迟。
虽然 buffer 和 cache 都涉及数据存储,但它们的目的和工作机制却有所不同:- Buffer 主要用于平衡 I/O 操作中的数据流动,确保数据的完整性。
- Cache 则侧重于提高数据访问速度,优化系统性能。
- Buffer 通常是顺序处理,按照数据的流向管理。
- Cache 则使用复杂的算法来决定哪些数据应该保留,以便快速访问。
咱们看一下系统中是怎么解释 Buffer 和 Cache的吧!要检查系统内存使用情况,您想到的第一个命令可能是 free ,例如:上面截图中,显示结果包括了物理内存 Mem 和 Swap 的具体使用情况(如总内存、已用内存、缓存、可用内存等)。缓存是 Buffer 和 Cache 两部分的总和。让我们看一下 free 的手册页中的 Buffer 和 Cache 定义:free 命令的源数据实际上存储在 proc/meminfo 文件中。/proc 文件系统也是许多性能工具的最终数据源。在 man proc 中,Buffers 和 Cached 的定义如下:看完上面的解释,有小伙伴们可能认为 Buffer 只是用于将数据写入磁盘的缓存,Cache 只是用于从文件中读取数据的缓存。但事实上,Buffer 也可以用于读取, Cache 也可以用于写入。
提醒,执行 echo3> /proc/sys/vm/drop_caches 导致的问题:- 释放缓存会导致后续读取文件时,需要重新从磁盘加载数据,短期内 IO 压力会增大;
- 生产环境除非必要,否则不要手动释放,内核的自动管理更高效。
让我们登录到我们的 Linux 主机并准备好两个终端。在终端 1,让我们先清理缓存:这里 /proc/sys/vm/drop_caches 是一个通过 proc 文件系统修改内核行为的例子。写入 3 意味着清理各种缓存,例如文件页、目录条目和 Inode。仍然在终端 1,让我们开启 vmstat 2 命令:- buff 和 cache 就是我们前面看到的 Buffer 和 Cache,单位是 KB。
- bi 和 bo 分别表示块设备读取和写入的大小,以块/s 为单位。由于 Linux 中的块大小为 1KB,因此这个单位相当于 KB/s。
现在切换回终端 1,并观察 buff 和 cache 的变化:同样在终端 1 中,再次启动 vmstat 2 命令:您可以看到此时 buff 为 0。现在在终端 2 中,运行以下命令:观察 vmstat 的输出,你会发现在读盘的时候(也就是 bi > 0 的时候),Buffer 和 Cache 都在增长,但是显然 Buffer 的增长要快很多。这意味着当从磁盘读取时,数据被缓存在 Buffer 中。根据这俩个测试,得出个结论:读取文件时数据会缓存在 Cache 中,读取磁盘时数据会缓存在 Buffer 中。