PageCache你应当不陌生了linux手机,假如你是一名应用开发者或则Linux运维人员,这么在工作中,你可能遇到过与PageCache有关的场景,例如:
这种问题,很可能是因为PageCache管理不到位导致的,由于PageCache管理不当不仅会降低系统I/O吞吐外,都会导致业务性能晃动,我在生产环境上处理过好多这类问题。
据我观察,这类问题出现后,业务开发人员以及运维人员常常会束手无策,究其缘由在于她们对PageCache的理解仅仅逗留在概念上,并不清楚PageCache怎样和应用、系统关联上去,对它引起的问题自然会束手无策了。所以,要想不再踩PageCache的坑,你必须对它有个清晰的认识。
这么在我看来,认识PageCache最简单的形式,就是用数据说话,通过具体的数据你会愈加深入地理解PageCache的本质。为了帮你消化和理解,用数据分析哪些是PageCachelinux最新内核版本,为何须要PageCache,PageCache的形成和回收是哪些样的。这样一来,你会从本质到假象,透彻理解它,真切体会它和你的应用程序之间的关系,因而能更好地理解前面提及的四个问题。
不过,在这儿我想给你提个醒,明天的内容,你最好具备一些Linux编程的基础,例如,怎样打开一个文件;怎么读写一个文件;怎么关掉一个文件等等。这样,你理解明天的内容会愈加容易,其实了,不具备也没有关系,假如遇见你实在看不懂的地方,你可以查阅《UNIX环境中级编程》这本书,它是每一位Linux开发者以及运维人员必读的入门书籍。
1
哪些是PageCache?
我记得好多应用开发者或则运维在向我寻求帮助,解决PageCache造成的问题时,总是喜欢问我PageCache究竟是属于内核还是属于用户?针对这样的问题,我通常会让她们先看下边这张图:
通过这张图片你可以清楚地听到,白色的地方就是PageCache,很显著,PageCache是内核管理的显存,也就是说,它属于内核不属于用户。
待会儿们如何来观察PageCache呢?虽然,在Linux上直接查看PageCache的方法有好多,包括/proc/meminfo、free、/proc/vmstat命令等,它们的内容似乎是一致的。
我们拿/proc/meminfo命令举例看一下(假如你想了解/proc/meminfo中每一项具体涵义的话,可以去看KernelDocumentation的meminfo这一节,它详尽解释了每一项的具体含意,KernelDocumentation是应用开发者想要了解内核最简单、直接的方法)。
$ 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
...
按照前面的数据,你可以简单得出这样的公式(方程两侧之和都是112696KB):
Buffers+Cached+SwapCached=Active(file)+Inactive(file)+Shmem+SwapCached
这么方程两侧的内容就是我们平常说的PageCache。请注意你没有看错,两侧都有SwapCached,之所以要把它放到方程里,就是说它也是PageCache的一部份。
接出来,我带你剖析一下这种项的具体含意。方程左边这种项把Buffers和Cached做了一下细分,分为了Active(file),Inactive(file)和Shmem,由于Buffers愈发依赖于内核实现,在不同内核版本中它的涵义可能有些不一致,而方程左边和应用程序的关系愈发直接,所以我们从方程左边来剖析。
在PageCache中,Active(file)+Inactive(file)是File-backedpage(与文件对应的显存页),是你最须要关注的部份。由于你平常用的mmap()显存映射方法和bufferedI/O来消耗的显存就属于这部份,**最重要的是,这部份在真实的生产环境上也最容易形成问题。
而SwapCached是在打开了Swap分区后,把Inactive(anon)+Active(anon)这两项里的匿名页给交换到c盘(swapout),之后再读入到显存(swapin)后分配的显存。因为读入到显存后原先的SwapFile还在,所以SwapCached也可以觉得是File-backedpage,即属于PageCache。这样做的目的也是为了减轻I/O。你是不是感觉这个过程有些复杂?我们用一张图直观地看一下:
我希望你能通过这个简单的示意图明白SwapCached是如何形成的。在这个过程中你要注意,SwapCached只在Swap分区打开的情况下才能有,而我建议你在生产环境中关掉Swap分区,由于Swap过程形成的I/O会很容易造成性能晃动。
不仅SwapCached,PageCache中的Shmem是指匿名共享映射这些方法分配的显存(free命令中shared这一项),例如tmpfs(临时文件系统),这部份在真实的生产环境中形成的问题比较少,不是我们明天的重点内容。
其实了,好多朋友也喜欢用free命令来查看系统中有多少PageCache,会依照buff/cache来判定存在多少PageCache。假如你对free命令有所了解的话,肯定晓得free命令也是通过解析/proc/meminfo得出这种统计数据的,这种都可以通过free工具的源码来找到。free命令的源码是开源,你可以去看下procfs里的free.c文件,源码是最直接的理解方法,它会加深你对free命令的理解。
不过你是否好奇过,free命令中的buff/cache到底是指哪些呢?我们在这儿先简单地看一下:
free -k
total used free shared buff/cache available
Mem: 7926580 7277960 492392 10000 156228 430680
Swap: 8224764 380748 7844016
通过procfs源码上面的proc/sysinfo.c这个文件,你可以发觉buff/cache包括下边这几项:
通过上面的数据我们也可以验证这个公式:1224+111472+43532的和是156228。
另外,这儿你要注意,你在做比较的过程中,一定要考虑到这种数据是动态变化的,并且执行命令本身也会带来显存开支,所以这个方程未必会严格相等linux运维面试题,不过你何必怀疑它的正确性。
从这个公式中,你能看见free命令中的buff/cache是由Buffers、Cached和SReclaimable这三项组成的,它指出的是显存的可回收性,也就是说,可以被回收的显存会统计在这一项。
其中SReclaimable是指可以被回收的内核显存,包括dentry和inode等。而这部份内容是内核特别细节性的东西,对于应用开发者和运维人员理解上去相对有些难度,所以我们在这儿不多说。
把握了PageCache具体由什么部份构成以后,在它引起一些问题时,你就能否晓得须要去观察哪些。例如说,应用本身消耗显存(RSS)不多的情况下,整个系统的显存使用率还是很高,那不妨去排查下是不是Shmem(共享显存)消耗了太多显存造成的。
说到这里,我想你应当对PageCache有了一些直观的认识了吧?其实了,有的人可能会说,内核的PageCache如此复杂,我不要不可以么?
我相信有这样看法的人不在少数,倘若不用内核管理的PageCache,那有两种思路来进行处理:
2
为何须要PageCache?
通过第一张图你虽然早已可以直观地听到,标准I/O和显存映射会先把数据写入到PageCache,这样做会通过降低I/O次数来提高读写效率。我们看一个具体的反例。首先,我们来世成一个1G大小的新文件,之后把PageCache清空,确保文件内容不在显存中linux最新内核版本,借此来比较第一次读文件和第二次读文件历时的差别。具体的流程如下。
先生成一个1G的文件:
ddif=/dev/zeroof=/home/yafang/test/dd.outbs=4096count=((1024*256))
其次,清空PageCache,须要先执行一下sync来将脏页同步到c盘再去dropcache。
$sync&&echo3>/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
通过这样详尽的过程你可以见到,第二次读取文件的历时远大于第一次的历时,这是由于第一次是从c盘来读取的内容,c盘I/O是比较历时的,而第二次读取的时侯因为文件内容早已在第一次读取时被读到显存了,所以是直接从显存读取的数据,显存相比c盘速率是快好多的。这就是PageCache存在的意义:降低I/O,提高应用的I/O速率。
所以,假若你不想为了很细致地管理显存而降低应用程序的复杂度,那你还是乖乖使用内核管理的PageCache吧,它是ROI(投入产出比)相对较高的一个方案。
你要晓得,我们在做方案决择时找到一个各方面都很完美的方案还是比较难的,大多数情况下都是经过权衡后来选择一个合适的方案。由于,我仍然深信,合适的就是最好的。
而我之所以说PageCache是合适的,而不是说它是最好的,那是由于PageCache的不足之处也是有的,这个不足之处主要彰显在,它对应用程序太过分透明,以至于应用程序很难有好方式来控制它。
3
总结
往期推荐
1
2
3
4