意见箱
恒创运营部门将仔细参阅您的意见和建议,必要时将通过预留邮箱与您保持联络。感谢您的支持!
意见/建议
提交建议

Page cache(页面缓存)

来源:佚名 编辑:佚名
2024-02-11 14:17:59

工作中,你可能经常遇到Page Cache相关场景,如:

服务器load飙升服务器I/O吞吐飙升业务响应时延出现突出的毛刺业务平均访问时延明显增加

这些都可能由于Page Cache使用不当导致,其不当使用不仅会增加系统I/O吞吐,还会引起业务性能抖动。

但很多 crud boy对Page Cache理解仅停留在概念上,完全不知道Page Cache怎么和应用系统联系。

要理解Page Cache,最直观的,就是show me数据,通过数据,能更深入理解Page Cache本质。

页缓存或文件缓存,是由好几个磁盘块构成,大小通常为4k,在64位系统上为8k,构成的几个磁盘块在物理磁盘上不一定连续,文件的组织单位为一页, 也就是一个page cache大小,文件读取是由外存上不连续的几个磁盘块,到buffer cache,然后组成page cache,然后供给应用程序。

Page cache在linux读写文件时,它用于缓存文件的逻辑内容,从而加快对磁盘上映像和数据的访问。具体说是加速对文件内容的访问,buffer cache缓存文件的具体内容——物理磁盘上的磁盘块,这是加速对磁盘的访问。

什么是 page cache

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是应用开发者想要了解内核最简单、直接的方式。

# cat /proc/meminfo
MemTotal: 4194304 kB
MemFree: 1076 kB
Buffers: 0 kB
Cached: 578160 kB
SwapCached: 0 kB
Active: 3680520 kB
Inactive: 472652 kB
Active(anon): 3575012 kB
Inactive(anon): 0 kB
Active(file): 105508 kB
Inactive(file): 472652 kB
Unevictable: 0 kB
Mlocked: 0 kB
SwapTotal: 4194304 kB
SwapFree: 4194304 kB
Dirty: 0 kB
Writeback: 0 kB
AnonPages: 3575068 kB
Mapped: 1492 kB
Shmem: 0 kB
Slab: 0 kB
SReclaimable: 0 kB
SUnreclaim: 0 kB
KernelStack: 0 kB
PageTables: 0 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 0 kB
Committed_AS: 0 kB
VmallocTotal: 0 kB
VmallocUsed: 0 kB
VmallocChunk: 0 kB
HardwareCorrupted: 0 kB
AnonHugePages: 0 kB

可得公式:

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

等式两边的内容就是Page Cache,SwapCached也是其中一部分。因为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:

Page cache(页面缓存)_应用程序_02

SwapCached只在Swap分区打开时才会有,但推荐生产环境关闭Swap分区,因为Swap过程产生的I/O很容易引起性能抖动。

Shmem

Page Cache的Shmem,匿名共享映射,一种分配内存的方式(free命令中shared这一项),比如tmpfs(临时文件系统),在生产环境故障较少,不过多关注。

很多人喜欢用free命令查看系统中有多少Page Cache,根据buff/cache判断存在多少Page Cache。free命令也是通过解析/proc/meminfo得出这些统计数据。free源码​​procfs​​的free.c文件。

# free -k
total used free shared buff/cache available
Mem: 4194304 3615372 1068 0 577508 409972
Swap: 4194304 0 4194304

通过procfs源码里面的​​proc/sysinfo.c​​这个文件,buff/cache包括:

buff/cache = Buffers + Cached + SReclaimable

验证公式: (0) + (577508) + (0)= 577508。

注意比较过程中,这些数据都是动态变化,且执行命令本身也会带来内存开销,所以等式难以严格相等,不过不用怀疑其正确性。

可见free命令的buff/cache=Buffers、Cached和SReclaimable,其强调内存的可回收性,即可以被回收的内存会统计在这一项。

SReclaimable:可被回收的内核内存,包括dentry和inode等。

知道Page Cache的构成,当其引发问题,就知道该观察什么。如应用本身消耗内存(RSS)不多,但整个系统内存使用率还是高,不妨排查下是不是Shmem(共享内存)消耗太多内存导致。

Page Cache这么复杂,如果不用内核管理的Page Cache,有两种思路处理:

应用程序维护自己的Cache做细粒度控制,如MySQL就是,参考MySQL Buffer Pool ,其实现复杂度还是很高的。就不如内核Page Cache来得简单高效。直接使用Direct I/O来绕过Page Cache,不使用Cache,省的去管它了。这可行吗?

说事实,讲证据,来看到底行不行。

为何需要Page Cache?

标准I/O和内存映射会先把数据写到Page Cache,这是通过减少I/O次数来提升读写效率。

案例

生成一个1G新文件,然后清空Page Cache,确保文件内容肯定不在内存,以此比较:

第一次读文件第二次读文件

的耗时的差异。

具体流程

先生成1G文件:

$ dd if=/dev/zero of=/home/yafang/test/dd.out bs=4096 count=$((1024*256))

清空Page Cache,需先执行sync将脏页同步到磁盘,再drop cache。

$ sync && echo 3 > /proc/sys/vm/drop_caches

第一次读文件耗时:

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

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

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

第二次读取文件的耗时<<第一次耗时:

第一次是从磁盘读取的内容,磁盘I/O较耗时第二次读取的时候由于文件内容已经在第一次读取时被读到内存,是直接从内存读取,内存相比磁盘速度快很多

这就是Page Cache的意义:减少I/O,提升应用的I/O速度。

若你不想为很细致地管理内存而增加应用程序的复杂度,就乖乖使用内核的Page Cache。

Page Cache是合适的,而非最好的,Page Cache也有不足,它对应用程序过于透明,应用程序无法控制它。

总结

管理好Page Cache,你要知道如何来观测它以及观测关于它的一些行为,有了这些数据做支撑,你才能够把它和你的业务更好地结合起来。

你某概念模糊时,最好的认知方式就是先搞明白如何观测,再动手观测它如何变化。

本网站发布或转载的文章均来自网络,其原创性以及文中表达的观点和判断不代表本网站。
上一篇: 物理网卡、网卡接口、内核、IP等属性的关系 下一篇: 手机怎么远程登录云服务器?