3

Linux 内存中的缓冲区(Buffer)与缓存(Cache)

 1 year ago
source link: https://os.51cto.com/article/708866.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
170e24176607eb86484332b0cba7436477d642.jpg

Buffer 和 Cache 的定义:

  • Buffer:是原始磁盘块的临时存储,即将缓存数据写入磁盘。它通常不会很大(大约  20MB)。这样,内核就可以将分散的写入集中起来,从而对磁盘写入进行统一优化。例如,多个小的写入可以合并为一个大的写入等。
  • Cache:是用于从磁盘读取文件的页面缓存,用于缓存从文件中读取的数据。这样,下次访问这些文件数据时,可以直接从内存中快速取回,而无需再次访问缓慢的磁盘。

但是让我问你,由于 Buffer 只是将写入磁盘的数据的缓存。反过来,它还会缓存从磁盘读取的数据吗?或者 Cache 是从文件中读取数据的缓存,那么它是否也为写入文件缓存数据呢?

如果你能回答以上两个问题,你可以跳过这篇文章,我想你已经对 Buffer 和 Cache 有了很好的理解。但如果你不能,请留下来看看我的进一步解释。

free 命令

要检查系统内存使用情况,您想到的第一个命令可能是 free ,例如:

$ free -h
              total        used        free      shared  buff/cache   available
Mem:           1.9G        1.0G        394M        2.6M        491M        728M
Swap:            0B          0B          0B

很明显,该输出包括了物理内存 Mem 和 Swap 的具体使用情况(如总内存、已用内存、缓存、可用内存等)。缓存是 Buffer 和 Cache 两部分的总和。

让我们看一下 free 的手册页中的  Buffer 和 Cache 定义:

buffers
              Memory used by kernel buffers (Buffers in /proc/meminfo)
cache         Memory used by the page cache and slabs (Cached and SReclaimable in /proc/meminfo)
buff/cache
              Sum of buffers and cache

我们可以看到 free 命令的源数据实际上存储在 proc/meminfo 文件中。正如我前面提到的,/proc 是 Linux 内核提供的一个特殊的文件系统,它就像一个用户与内核交互的接口。

/proc 文件系统也是许多性能工具的最终数据源。在 man proc 中,Buffers 和 Cached 的定义如下:

Buffers %lu
    Relatively temporary storage for raw disk blocks that shouldn't get tremendously large (20MB or so).
Cached %lu
   In-memory cache for files read from the disk (the page cache).  Doesn't include SwapCached.
...
SReclaimable %lu (since Linux 2.6.19)
    Part of Slab, that might be reclaimed, such as caches.
SUnreclaim %lu (since Linux 2.6.19)
    Part of Slab, that cannot be reclaimed on memory pressure.

至此,您可能认为您已经找到了我的问题的答案,“Buffer”只是用于将数据写入磁盘的缓存,“Cache”只是用于从文件中读取数据的缓存。但事实上,“Buffer”也可以用于读取,“Cache”也可以用于写入。

我们将在这里做两个实验,写缓存和读缓存。

写入 Cache

让我们登录到我们的 Linux 主机并准备好两个终端。在终端 1,让我们先清理缓存:

2748b6a6931db80d5bf1259220ff818705d076.jpg

这里 /proc/sys/vm/drop_caches 是一个通过 proc 文件系统修改内核行为的例子。写入 3 意味着清理各种缓存,例如文件页、目录条目和 Inode。

仍然在终端 1,让我们开启 vmstat 2 命令:

d35f7fd86322f8e1a8b505f2e8ed6f49cf9977.jpg
  • buff 和 cache 就是我们前面看到的 Buffer 和 Cache,单位是 KB。
  • bi 和 bo 分别表示块设备读取和写入的大小,以块/s 为单位。由于 Linux 中的块大小为 1KB,因此这个单位相当于 KB/s。

接下来,转移到终端 2 并运行以下命令:

07a09405289bc4bcbfe30385485e2d3923435f.jpg

现在切换回终端 1,并观察 buff 和 cache 的变化:

533dacf52d0d744ee05502539199ac53df962f.jpg

通过观察 vmstat 的输出,我们发现运行 dd 命令时,Cache 一直在增长,而 Buffer 基本没有变化。

读取 Buffer

现在,让我们做第二个实验。再次清除终端 1中的缓存:

42fa28916d5ab82b16b681698276067d594c94.jpg

同样在终端 1 中,再次启动 vmstat 2 命令:

a8f036599c006957e1b328e6fb6491d54a6af6.jpg

您可以看到此时 buff 为 0。现在在终端 2 中,运行以下命令:

e771c9b0974a358ba900620556f039e372efeb.jpg

然后,回到终端 1 观察:

84f03f2971918ed52ee6478f464715c3de92e1.jpg

观察 vmstat 的输出,你会发现在读盘的时候(也就是 bi > 0 的时候),Buffer 和 Cache 都在增长,但是显然 Buffer 的增长要快很多。这意味着当从磁盘读取时,数据被缓存在 Buffer 中。

现在我们几乎可以得出结论:

读取文件时数据会缓存在 Cache 中,读取磁盘时数据会缓存在 Buffer 中。

在这里您应该会发现,虽然本文对 Buffer 和 Cache 进行了描述,但仍然无法涵盖所有细节。我们如今学到了以下两点:

  • Buffer:既可以用作“要写入磁盘的数据缓存”,也可以用作“读取磁盘读的数据缓存”。
  • Cache:既可以用作“从读取文件的页面缓存”,也可以用作“写入文件的页面缓存”。

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK