2-PageCachechan产生释放及优化( 四 )


Page Cache 是在应用程序读写文件的过程中产生的,所以在读写文件之前你需要留意 是否还有足够的内存来分配 Page Cache;
Page Cache 中的脏页很容易引起问题,你要重点注意这一块;
在系统可用内存不足的时候就会回收 Page Cache 来释放出来内存,
我建议你可以通过sar 或者 /proc/ 来观察这个行为从而更好的判断问题是否跟回收有关
Page Cache难以回收产生的load(负载)飙高
系统很卡顿,敲命令响应非常慢;应用程序的 RT 变得很高,或者抖动得很厉害 。在发生这些问题时,很有可能也伴随着 系统 load 飙得很高 。
导致飙高的原因一般是下面三种:
直接内存回收引起的 load 飙高; 系统中脏页积压过多引起的 load 飙高; 系统 NUMA 策略(内存配置策略)配置不当引起的 load 飙高 。
直接内存回收引起 load 飙高或者业务时延抖动
直接内存回收是指在进程上下文同步进行内存回收 因为直接内存回收是在进程申请内存的过程中同步进行的回收,而这个回收过程可能会消耗很多时间,进而导致进程的后续行为都被迫等待,这样就会造成很长时间的延迟,以及 系统的 CPU 利用率会升高,最终引起 load 飙高 。
? 内存回收过程图
在开始内存回收后,首先进行后台异步回收(上图中蓝色标记的地方),这不会引起进程的延迟;如果后台异步回收跟不上进行内存申请的速度,就会开始同步阻塞回收,导致延迟(上图中红色和粉色标记的地方,这就是引起 load 高的地址)
针对直接内存回收引起 load 飙高或者业务 RT 抖动的问题,一个解决方案就是及早地触发后台回收来避免应用程序进行直接内存回收
原理图
当内存水位低于low 时,就会唤醒进行后台回收,然后会一直回收到high
我们可以增大这个配置选项来及早地触发后台回收,该选项最终控制的是内存回收水位,不过,内存回收水位是内核里面非常细节性的知识点我们可以先不去讨论 。
vim /etc/sysctl.conf vm.min_free_kbytes = 4194304
vm. =
对于大于等于 128G 的系统而言,将设置为 4G 比较合理,这是我们在处理很多这种问题时总结出来的一个经验值,既不造成较多的内存浪费,又能避免掉绝大多数的直接内存回收 。
该值的设置和总的物理内存并没有一个严格对应的关系
你可以渐进式地增大该值,比如先调整为 1G,观察 sar -B 中是否还有不为 0 的情况;如果存在不为 0 的情 况,继续增加到 2G,再次观察是否还有不为 0 的情况来决定是否增大,以此类推
在这里你需要注意的是,即使将该值增加得很大,还是可能存在不为 0 的情况 那么这个时候你要考虑的是,业务是否可以容忍,如果可以容忍那就没有 必要继续增加了,也就是说,*增大该值并不是完全避免直接内存回收,而是尽量将直接内存回收行为控制在业务可以容忍的范围内 *
这个方法可以用在 3.10.0 以后的内核上
然了,这样做也有一些缺陷:提高了内存水位后,应用程序可以直接使用的内存量就会 减少,这在一定程度上浪费了内存 。
*应用程序更加关注什么,如果关注延迟那就适当地增大该值,如果关注内存的使用量那就适当地调小该值 。*
通过调整内存水位,在一定程度上保障了应用的内存申请,但是同时也带来了一定的内存浪费,因为系统始终要保障有这么多的 free 内存,这就压缩了 Page Cache 的空间 。调整的效果你可以通过 /proc/ 来观察:
$ egrep "min|low|high" /proc/zoneinfo...min 7019low 8773high 10527