什么是 Page Cache?

image.png

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

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

查看 Page Cache:

  1. $ cat /proc/meminfo
  2. ...
  3. Buffers: 1224 kB
  4. Cached: 111472 kB
  5. SwapCached: 36364 kB
  6. Active: 6224232 kB
  7. Inactive: 979432 kB
  8. Active(anon): 6173036 kB
  9. Inactive(anon): 927932 kB
  10. Active(file): 51196 kB
  11. Inactive(file): 51500 kB
  12. ...
  13. Shmem: 10000 kB
  14. ...
  15. SReclaimable: 43532 kB
  16. ...

内存计算:

  • Buffers + Cached + SwapCached = Active(file) + Inactive(file) + Shmem + SwapCached
    • Buffers + Cached 拆分为 Active(file) + Inactive(file) + Shmem
  • 等式两边的内容就是我们平时说的 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。

image.png

  • 建议在生产环境中关闭 Swap 分区,因为 Swap 过程产生的 I/O 会很容易引起性能抖动。

Shmem 是指匿名共享映射这种方式分配的内存(free 命令中 shared 这一项),比如 tmpfs(临时文件系统),这部分在真实的生产环境中产生的问题比较少.

free 命令中的 buff/cache

  1. $ free -k
  2. total used free shared buff/cache available
  3. Mem: 7926580 7277960 492392 10000 156228 430680
  4. Swap: 8224764 380748 7844016
  • buff/cache = Buffers + Cached + SReclaimable
  • 强调的是内存的可回收性,也就是说,可以被回收的内存会统计在这一项
  • SReclaimable 是指可以被回收的内核内存,包括 dentry 和 inode 等

不使用 Page Cache 的思路

  • 第一种,应用程序维护自己的 Cache 做更加细粒度的控制,比如 MySQL 就是这样做的,你可以参考MySQL Buffer Pool ,它的实现复杂度还是很高的。对于大多数应用而言,实现自己的 Cache 成本还是挺高的,不如内核的 Page Cache 来得简单高效。
  • 第二种,直接使用 Direct I/O 来绕过 Page Cache,不使用 Cache 了,省的去管它了。这种方法可行么?那我们继续用数据说话,看看这种做法的问题在哪儿?

为什么需要 Page Cache?

  1. 先生成一个 1G 文件
  1. $ ddif=/dev/zeroof=/home/yafang/test/dd.outbs=4096count=((1024*256))
  1. 其次,清空 Page Cache,需要先执行一下 sync 来将脏页同步到磁盘再去 drop cache
  1. $ sync && echo 3 > /proc/sys/vm/drop_caches

第一次读取文件的耗时如下:

  1. $ time cat /home/yafang/test/dd.out &> /dev/null
  2. real 0m5.733s
  3. user 0m0.003s
  4. sys 0m0.213s

再次读取文件的耗时如下:

  1. $ time cat /home/yafang/test/dd.out &> /dev/null
  2. real 0m0.132s
  3. user 0m0.001s
  4. sys 0m0.130s

Page Cache 存在的意义:减少 I/O,提升应用的 I/O 速度。
**