Linux内核技术5 Page Cache - 如何判断问题是否由Page Cache产生的?

如何精确定位为题是否由Page Cache导致

我们知道一个问题的产生往往会牵扯到操作系统的很多模块,比如说,当系统出现 load 飙高的问题时,可能是 Page Cache 引起的;也可能是锁冲突太厉害,物理资源(CPU、内存、磁盘 I/O、网络 I/O)有争抢导致的;也可能是内核特性设计缺陷导致的。

当问题发生时,我们需要精确定位到问题产生的原因,才好对症下药,盲目采取策略可能会使得我们的系统雪上加霜。

Linux的典型分析手段
/proc 和 /sys
Linux 内核主要是通过 /proc 和 /sys 把系统信息导出给用户, 当系统出现问题时,我们可以试着去这几个目录下读取一下系统信息,看看哪些指标异常。

如何大致判断问题是否由Page Cache引起
我们可以读取proc/vmstat中的pgscan在单位时间内的变化,如果变化过大,说明问题可能是由于Page Cache引起的,因为 pgscan 代表了 Page Cache 的内存回收行为,它变化较大往往意味着系统内存压力很紧张。

image.png

如何分析问题的产生
/proc 和 /sys 里面的信息可以给我们指出一个问题分析的大致方向,我们可以判断出问题是不是由 Page Cache 引起的。然后我们可以用一些专业的工具(比如ftrace,ebpf,perf等)对问题进行更加深入的分析,从而了解问题是如何产生的。

如何选用合适的工具
静态追踪(预置了追踪点)和动态追踪(需要借助 probe)
如果你想要追踪的东西已经有了预置的追踪点,那你直接使用这些预置追踪点就可以 了; 如果没有预置追踪点,那你就要看看是否可以使用 probe(包括 kprobe 和 uprobe) 来 实现。

需要注意的是,分析工具自身也会对业务造成一些影响(Heisenbug),比如说使用 strace 会阻塞进程的运行,再比如使用 systemtap 也会有加载编译的开销等,所以我们在使用这些工具之前也需要去详细了解下这些工具的副作用,以免引起意料之外的问题。

image.png

实时问题分析
系统现在 load 很高,是由 Page Cache 引起的吗?
1.优先使用系统自带工具检查概况,上手简单:

sar -B #分析分页信息 (Paging statistics)
sar -r #分析内存使用情况统计 (Memory utilization statistics) 
复制代码

在Linu内核4.20之后,如果sar也升级到了12.3.3版本的话,我们可以使用sar新增的PSI功能, 同样这些信息也会记载在/proc/pressure文件中:

CPU format

some avg10=0.00 avg60=0.00 avg300=0.00 total=0
full avg10=0.00 avg60=0.00 avg300=0.00 total=0
复制代码

我们需要重点关注 avg10 这一列,它表示最近 10s 内存的平均压力情况,如果它很大(比如 大于 40)那 load 飙高大概率是由于内存压力,尤其是 Page Cache 的压力引起的。

参考文档: PSI - Pressure Stall Information — The Linux Kernel documentation

2.采集指标,定位问题点
sar 采集的只是一些常用的指标,它并没有覆盖 Page Cache 的所有行为,比如说内存规整(memory compaction)、业务 workingset 等这些容易引起 load 飙高的问题点。

采集完这些指标后,我们就可以分析 Page Cache 异常是由什么引起的了。 举个例子,当单位时间内 compact_fail 变化很大时,说明碎片整理失败次数很多,也意味着系统内存碎片很严重,已经很难申请到连续物理内存了,这时你就需要去调整碎片指数或者手动触发内存规整,来减缓因为内存碎片引起的压力了。

Page Cache常见指标速查

image.png

3.打破砂锅问到底,进一步分析问题
针对上面那个问题,我们需要知道是什么东西在进行连续内存的申请,从而来做更加有针对性的调整,这就需要进行进一步的观察了。

利用内核预置的相关 tracepoint 来做更加细致的分析

image.png

计算内存规整带来的延迟
内存规整 (memory compaction) 为例,来看下如何利用 tracepoint 来对它进行观察:

#触发compaction相关时间
$ echo 1 >
/sys/kernel/debug/tracing/events/compaction/mm_compaction_begin/enable
$ echo 1 >
/sys/kernel/debug/tracing/events/compaction/mm_compaction_end/enable 

#然后来读取信息,当compaction事件触发后就会有信息输出
$ cat /sys/kernel/debug/tracing/trace_pipe
 <...>-49355 [037] .... 1578020.975159: mm_compaction_begin: 
zone_start=0x2080000 migrate_pfn=0x2080000 free_pfn=0x3fe5800 
zone_end=0x4080000, mode=async
 <...>-49355 [037] .N.. 1578020.992136: mm_compaction_end: 
zone_start=0x2080000 migrate_pfn=0x208f420 free_pfn=0x3f4b720 
zone_end=0x4080000, mode=async status=contended
复制代码

可以看到是 49355 这个进程触发了 compaction,begin 和 end 这两个 tracepoint 触发的时间戳相减,就可以得到 compaction 给业务带来的延迟,我们可以计算出这一次的延迟为 17ms.

有时候我们采集的数据太多,往往需要自动化分析工具帮我们来进行问题分析,比如: perf-script(1) - Linux manual page (man7.org)

历史问题分析
系统 load 值在昨天飙得很高,是由 Page Cache 引起的吗?
对实时问题来说,因为有现场信息可供采集,所以相对好分析一些。
但是有时候,我们没有办法及时地去搜集现场信息,比如问题发生在深夜时,我们没有来得及去采集现场信息,这个时候就只能查看历史记录了。

Sar日志信息
我们可以根据 sar 的日志信息来判断当时发生了什么事情, 比如我们的业务系统昨晚出现了RT抖动,通过查看日志我们发现业务 RT 抖动的时间和 sar -B 里的 pgscand 不为 0 的时刻在很多时刻都是吻合的。所以我们可以推断业务抖动可能跟 Page Cache 回收存在一些关系,我们可以尝试调大vm.min_free_kbytes 来验证效果,看看业务是否还有抖动。

Tips: 调整 vm.min_free_kbytes 会存在一些风险,如果系统本身 内存回收已经很紧张,再去调大它极有可能触发 OOM 甚至引起系统宕机。所以在调大的时候,一定要先做一些检查,看看此时是否可以调整。

Sar 命令补充20 sar command examples in Linux [Cheat Sheet] | GoLinuxCloud

猜你喜欢

转载自juejin.im/post/7102678421448163364