一、常见与Page Cache有关场景

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

二、什么是Page Cache?

1、观察Page Cache方式

  1. /proc/vmstat
  2. /proc/meminfo
  3. free

1.1、/proc/meminfo

cat /pro/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 
...
* **Buffers + Cached + SwapCached = Active(file) + Inactive(file) + Shmem + SwapCached**
	* 等式右边这些项目把Buffers和Cached细分了,分成了Active(file)、Inactive(file)和Shmem
	* Buffers更加依赖于内核实现,在不同内核版本中含义可能不一致
	* 等式右边和应用程序的关系更加直接
* **Active(file)+Inactive(file)**
	* File-backed page(与文件对应的内存页)
		* mmap()内存映射方式和buffered I/O来消耗的内存就属于这部分
		* 实际生产环境最容易产生问题
* **SwapCached**
	* 是打开了swap后,把Inactive(anon)+Active(anon)这两项里匿名页(比如进程的堆、栈等,没有一个文件作为back store)给交换磁盘(swap out),然后再读入到内存(swap in)后分配的内存
	* 读入到内存后原来的Swap File还在,所以SwapCached也可以认为是File-bcached page,即属于Page Cache
	* 目的:减少I/O
	* SwapCached产生过程
		![](https://s4.51cto.com/images/blog/202009/17/1cf614cb45453dc5fcb9ea624f5c1995.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=)
		* SwapCache只在Swap分区打开情况下才会有,Swap过程产生的I/O会很容易引起抖动
* **Shmem**
	* 是指匿名共享映射这种方式分配的内存(free命令中的shared这一项)
	* 比如:tmpfs(临时文件系统)
	* 此部分生产环境中问题比较少

1.2、free

$ free -k
              total        used        free      shared  buff/cache   available
Mem:        7926580     7277960      492392       10000      156228      430680
Swap:       8224764      380748     7844016
  • 通过解析/proc/meminfo统计所得
  • 源码:procfs中free.c文件
    • buff/cache = Buffers + Cached + SReclaimable
      • 强调内存的可回收性
      • Sreclaimable是指被回收的内核内存,包括dentry和inode等
    • 验证公式:1224+111472+43532=156228
    • 注意:数据是动态变化,执行命令本身会带来内存开销,等式未必严格相等。

1.3、是否可以不要Page Cache?

  • 思路1:应用程序维护自己的Cache做更加细粒度的控制
    • 比如:MySQL,参考MySQL Buffer Pool,实现复杂度高,不如内核的Page Cache简单高效
  • 思路2:使用Direct I/O绕过Page Cache(见下方分析)

1.4、为什么需要Page Cache?

  • 标准I/O、内存映射会先把数据写入到Page Cache
    • 目的:介绍I/O次数来提升读写效率
    • 案例:
	1、生成一个1G大小的新文件 
dd if=/dev/zero of=/home/test/dd.out bs=4096 count=((1024*256)) 
2、把Page Cache清空 
echo 3 >/proc/sys/vm/drop_caches 
3、确保文件内容不再内存中 
4、比较第一次读文件和第二次读文件耗时差异 
time cat /home/test/dd.out &> /dev/null
* 分析
	* 第二次读取文件的耗时远小于第一次耗时,因为第一次从磁盘来读取的内容,磁盘I/O比较耗时,第二次读取的时候由于文件内容已经在第一次读取到内存了,所以直接从内存读取的数据
* Page Cache存在的意义
	* **减少I/O,提升应用的I/O速度**

=================== END ===================