如何用数据观测Page Cache?

目录

背景

什么是 Page Cache?

为什么需要 Page Cache?

小结


背景

Page Cache 你应该不陌生了,如果你是一名应用开发者或者 Linux 运维人员,那么在工作中,你可能遇见过与 Page Cache 有关的场景,比如:

  1. 服务器的 load 飙高;
  2. 服务器的 I/O 吞吐飙高;
  3. 业务响应时延出现大的毛刺;
  4. 业务平均访问时延明显增加。

这些问题,很可能是由于 Page Cache 管理不到位引起的,因为 Page Cache 管理不当除了会增加系统 I/O 吞吐外,还会引起业务性能抖动,我在生产环境上处理过很多这类问题。

什么是 Page Cache?

 应用程序产生Page Cache的逻辑示意图

通过这张图片你可以清楚地看到,红色的地方就是 Page Cache,很明显,Page Cache是内核管理的内存,也就是说,它属于内核不属于用户。

那咱们怎么来观察 Page Cache 呢?其实,在 Linux 上直接查看 Page Cache 的方式有很多,包括 /proc/meminfo、free 、/proc/vmstat 命令等,它们的内容其实是一致的。

我们拿 /proc/meminfo 命令举例看一下(如果你想了解 /proc/meminfo 中每一项具体含义的话,可以去看 Kernel Documentation的 meminfo 这一节,它详细解释了每一项的具体含义,Kernel Documentation 是应用开发者想要了解内核最简单、直接的方式)。

Kernel Documentation的 meminfo 这一节参考如下链接:https://www.kernel.org/doc/Documentation/filesystems/proc.rst

$ cat /proc/meminfo
...
Buffers:1224 kB
Cached:111472 kB
SwapCached:36364 KB
Active:6224232 kB
Inactive:979432 kB
Active(anon):6173036 kB
Inactive(anon):927932 kB
Active(file):51196 kB
Inactive(file):51500 kB
...
Shmem:10000 kB
SReclaimable:43532 kB

根据上面的数据,你可以简单得出这样的公式(等式两边之和都是 112696 KB):

Buffers + Cached + SwapCached = Active(file) + Inactive(file) + Shmem +SwapCached

那么等式两边的内容就是我们平时说的 Page Cache。请注意你没有看错,两边都SwapCached,之所以要把它放在等式里,就是说它也是 Page Cache 的一部分。

接下来,我带你分析一下这些项的具体含义。等式右边这些项把 Buffers 和 Cached 做了一下细分,分为了 Active(file),Inactive(file) 和 Shmem,因为 Buffers 更加依赖于内核实现,在不同内核版本中它的含义可能有些不一致,而等式右边和应用程序的关系更加直接,所以我们从等式右边来分析。

在 Page Cache 中,Active(file)+Inactive(file) 是 File-backed page(与文件对应的内存页),是你最需要关注的部分。因为你平时用的 mmap() 内存映射方式和 buffered I/O来消耗的内存就属于这部分,最重要的是,这部分在真实的生产环境上也最容易产生问题,我们在接下来的案例会重点分析它。

而 SwapCached 是在打开了 Swap 分区后,把 Inactive(anon)+Active(anon) 这两项里的匿名页给交换到磁盘(swap out),然后再读入到内存(swap in)后分配的内存。由于读入到内存后原来的 Swap File 还在,所以 SwapCached 也可以认为是 File-backed page,即属于 Page Cache。这样做的目的也是为了减少 I/O。你是不是觉得这个过程有些复杂?我们用一张图直观地看一下:

 我希望你能通过这个简单的示意图明白 SwapCached 是怎么产生的。在这个过程中你要注意,SwapCached 只在 Swap 分区打开的情况下才会有,而我建议你在生产环境中关闭Swap 分区,因为 Swap 过程产生的 I/O 会很容易引起性能抖动。

除了 SwapCached,Page Cache 中的 Shmem 是指匿名共享映射这种方式分配的内存(free 命令中 shared 这一项),比如 tmpfs(临时文件系统),这部分在真实的生产环境中产生的问题比较少,不是我们今天的重点内容,我们不对它做过多关注,你知道有这回事就可以了。

当然了,很多同学也喜欢用 free 命令来查看系统中有多少 Page Cache,会根据buff/cache 来判断存在多少 Page Cache。如果你对 free 命令有所了解的话,肯定知道free 命令也是通过解析 /proc/meminfo 得出这些统计数据的,这些都可以通过 free 工具的源码来找到。free 命令的源码是开源,你可以去看下  procfs里的 free.c 文件,源码是最直接的理解方式,它会加深你对 free 命令的理解。

不过你是否好奇过,free 命令中的 buff/cache 究竟是指什么呢?我们在这里先简单地看一下:

wj@wj:~$ free -h
               total        used        free      shared  buff/cache   available
Mem:            54Gi       9.1Gi       744Mi       1.3Gi        44Gi        43Gi
Swap:           86Gi       1.0Mi        86Gi

通过 procfs 源码里面的  proc/sysinfo.c这个文件,你可以发现 buff/cache 包括下面这几项:

buff/cache = Buffers + Cached + SReclaimable

通过前面的数据我们也可以验证这个公式: 1224 + 111472 + 43532 的和是 156228。

另外,这里你要注意,你在做比较的过程中,一定要考虑到这些数据是动态变化的,而且执行命令本身也会带来内存开销,所以这个等式未必会严格相等,不过你不必怀疑它的正确性。

从这个公式中,你能看到 free 命令中的 buff/cache 是由 Buffers、Cached 和SReclaimable 这三项组成的,它强调的是内存的可回收性,也就是说,可以被回收的内存会统计在这一项。

其中 SReclaimable 是指可以被回收的内核内存,包括 dentry 和 inode 等。而这部分内容是内核非常细节性的东西,对于应用开发者和运维人员理解起来相对有些难度,所以我们在这里不多说。

掌握了 Page Cache 具体由哪些部分构成之后,在它引发一些问题时,你就能够知道需要去观察什么。比如说,应用本身消耗内存(RSS)不多的情况下,整个系统的内存使用率还是很高,那不妨去排查下是不是 Shmem(共享内存) 消耗了太多内存导致的。

讲到这儿,我想你应该对 Page Cache 有了一些直观的认识了吧?当然了,有的人可能会说,内核的 Page Cache 这么复杂,我不要不可以么?

第一种,应用程序维护自己的 Cache 做更加细粒度的控制,比如 MySQL 就是这样做的,你可以参考  MySQL Buffer Pool ,它的实现复杂度还是很高的。对于大多数应用而言,实现自己的 Cache 成本还是挺高的,不如内核的 Page Cache 来得简单高效。

第二种,直接使用 Direct I/O 来绕过 Page Cache,不使用 Cache 了,省的去管它了。这种方法可行么?那我们继续用数据说话,看看这种做法的问题在哪儿?

为什么需要 Page Cache?

通过第一张图你其实已经可以直观地看到,标准 I/O 和内存映射会先把数据写入到 Page Cache,这样做会通过减少 I/O 次数来提升读写效率。我们看一个具体的例子。首先,我们来生成一个 1G 大小的新文件,然后把 Page Cache 清空,确保文件内容不在内存中,以此来比较第一次读文件和第二次读文件耗时的差异。具体的流程如下。

先生成一个 1G 的文件:

//未完待续....

小结

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

repinkply

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值