You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

127 lines
13 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 05 分析篇 | 如何判断问题是否由Page Cache产生的
你好,我是邵亚方。
在前面几节课里我们讲了Page Cache的一些基础知识以及如何去处理Page Cache引发的一些问题。这节课我们来讲讲如何判断问题是不是由Page Cache引起的。
我们知道一个问题往往牵扯到操作系统的很多模块比如说当系统出现load飙高的问题时可能是Page Cache引起的也可能是锁冲突太厉害物理资源CPU、内存、磁盘I/O、网络I/O有争抢导致的也可能是内核特性设计缺陷导致的等等。
如果我们没有判断清楚问题是如何引起的而贸然采取措施非但无法解决问题反而会引起其他负面影响比如说load飙高本来是Page Cache引起的如果你没有查清楚原因而误以为是网络引起的然后对网络进行限流看起来把问题解决了但是系统运行久了还是会出现load飙高而且限流这种行为还降低了系统负载能力。
那么当问题发生时我们如何判断它是不是由Page Cache引起的呢
## Linux问题的典型分析手段
Linux上有一些典型的问题分析手段从这些基本的分析方法入手你可以一步步判断出问题根因。这些分析手段可以简单地归纳为下图
![](https://static001.geekbang.org/resource/image/ee/c1/ee08329fc5eb7fb8ddff14dba9ebf0c1.jpg "Linux的典型分析手段")
从这张图中我们可以看到Linux内核主要是通过/proc和/sys把系统信息导出给用户当你不清楚问题发生的原因时你就可以试着去这几个目录下读取一下系统信息看看哪些指标异常。比如当你不清楚问题是否由Page Cache引起时你可以试着去把/proc/vmstat里面的信息给读取出来看看哪些指标单位时间内变化较大。如果pgscan相关指标变化较大那就可能是Page Cache引起的因为pgscan代表了Page Cache的内存回收行为它变化较大往往意味着系统内存压力很紧张。
/proc和/sys里面的信息可以给我们指出一个问题分析的大致方向我们可以判断出问题是不是由Page Cache引起的但是如果想要深入地分析问题知道Page Cache是如何引起问题的我们还需要掌握更加专业的分析手段专业的分析工具有ftraceebpfperf等。
当然了,这些专业工具的学习成本也相对略高一些,但你不能觉得它难、成本高,就不学了,因为掌握了这些分析工具后,再遇到疑难杂症,你分析起来会更加得心应手。
为了让你在遇到问题时更加方便地找到合适的分析工具,我借用[Bredan Gregg的一张图](https://www.slideshare.net/brendangregg/velocity-2015-linux-perf-tools/107),并根据自己的经验,把这张图略作了一些改进,帮助你学习该如何使用这些分析工具:
![](https://static001.geekbang.org/resource/image/0c/97/0ccc072485d8ca2b995a6e7b6a75da97.jpg)
在这张图里整体上追踪方式分为了静态追踪预置了追踪点和动态追踪需要借助probe
* 如果你想要追踪的东西已经有了预置的追踪点,那你直接使用这些预置追踪点就可以了;
* 如果没有预置追踪点那你就要看看是否可以使用probe(包括kprobe和uprobe)来实现。
因为分析工具自身也会对业务造成一些影响Heisenbug比如说使用strace会阻塞进程的运行再比如使用systemtap也会有加载编译的开销等**所以我们在使用这些工具之前也需要去详细了解下这些工具的副作用,以免引起意料之外的问题**。
比如我多年以前在使用systemtap的guru专家模式的时候因为没有考虑到systemtap进程异常退出后可能不会卸载systemtap模块从而引发系统panic的问题。
上面这些就是Linux问题的一些典型分析方法了解了这些分析方法你再遇到问题就能知道该选择什么样的工具来去分析。对于Page Cache而言首先我们可以通过/proc/vmstat来做一个大致判断然后再结合Page Cache的tracepoint来做更加深入的分析。
接下来我们一起分析两个具体问题。
## 系统现在load很高是由Page Cache引起的吗
我相信你肯定会遇到过这种场景业务一直稳定运行着却忽然出现很大的性能抖动或者系统一直稳定运行着却忽然出现较高的load值那怎么去判断这个问题是不是由Page Cache引起的呢在这里我根据自己多年的经验总结了一些分析的步骤。
分析问题的第一步就是需要对系统的概括做一个了解对于Page Cahe相关的问题我推荐你**使用sar来采集Page Cache的概况**,它是系统默认配置好的工具,使用起来非常简单方便。
我在课程的第1讲也提到了对sar的一些使用比如通过sar -B来分析分页信息(Paging statistics) 以及sar -r来分析内存使用情况统计(Memory utilization statistics)等。在这里我特别推荐你使用sar里面记录的PSIPressure-Stall Information信息来查看Page Cache产生压力情况尤其是给业务产生的压力而这些压力最终都会体现在load上。不过该功能需要4.20以上的内核版本才支持同时sar的版本也要更新到12.3.3版本以上。比如PSI中表示内存压力的如下输出
```
some avg10=45.49 avg60=10.23 avg300=5.41 total=76464318
full avg10=40.87 avg60=9.05 avg300=4.29 total=58141082
```
你需要重点关注avg10这一列它表示最近10s内存的平均压力情况如果它很大比如大于40那load飙高大概率是由于内存压力尤其是Page Cache的压力引起的。
明白了概况之后我们还需要进一步查看究竟是Page Cache的什么行为引起的系统压力。
因为sar采集的只是一些常用的指标它并没有覆盖Page Cache的所有行为比如说内存规整memory compaction、业务workingset等这些容易引起load飙高的问题点。在我们想要分析更加具体的原因时就需要去采集这些指标了。通常在Page Cache出问题时这些指标中的一个或多个都会有异常这里我给你列出一些常见指标
![](https://static001.geekbang.org/resource/image/ed/bb/ed990308aef09a5918e6855362284dbb.jpg)
采集完这些指标后我们就可以分析Page Cache异常是由什么引起的了。比如说当我们发现单位时间内compact\_fail变化很大时那往往意味着系统内存碎片很严重已经很难申请到连续物理内存了这时你就需要去调整碎片指数或者手动触发内存规整来减缓因为内存碎片引起的压力了。
我们在前面的步骤中采集的数据指标可以帮助我们来定位到问题点究竟是什么比如下面这些问题点。但是有的时候我们还需要知道是什么东西在进行连续内存的申请从而来做更加有针对性的调整这就需要进行进一步的观察了。我们可以利用内核预置的相关tracepoint来做更加细致的分析。
![](https://static001.geekbang.org/resource/image/f1/f0/f14faca88b5a765690a6c1540517def0.jpg)
我们继续以内存规整(memory compaction)为例来看下如何利用tracepoint来对它进行观察
```
#首先来使能compcation相关的一些tracepoing
$ 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这个进程触发了compactionbegin和end这两个tracepoint触发的时间戳相减就可以得到compaction给业务带来的延迟我们可以计算出这一次的延迟为17ms。
很多时候由于采集的信息量太大,我们往往需要借助一些自动化分析的工具来分析,这样会很高效。比如我之前写过一个[perf script](https://lore.kernel.org/linux-mm/20191001144524.GB3321@techsingularity.net/T/)来分析直接内存回收对业务造成的延迟。另外你也可以参考Brendan Gregg基于bcc(eBPF)写的[direct reclaim snoop](https://github.com/iovisor/bcc/blob/master/tools/drsnoop.py)来观察进程因为direct reclaim而导致的延迟。
## 系统load值在昨天飙得很高是由Page Cache引起的吗
上面的问题是实时发生的,对实时问题来说,因为有现场信息可供采集,所以相对好分析一些。但是有时候,我们没有办法及时地去搜集现场信息,比如问题发生在深夜时,我们没有来得及去采集现场信息,这个时候就只能查看历史记录了。
我们可以根据sar的日志信息来判断当时发生了什么事情。我之前就遇到过类似的问题。
曾经有一个业务反馈说RT抖动得比较明显让我帮他们分析一下抖动的原因我把业务RT抖动的时间和sar -B里的pgscand不为0的时刻相比较后发现二者在很多时候都是吻合的。于是我推断业务抖动跟Page Cache回收存在一些关系然后我让业务方调vm.min\_free\_kbytes来验证效果业务方将该值从初始值90112调整为4G后效果立竿见影就几乎没有抖动了。
在这里我想再次强调一遍调整vm.min\_free\_kbytes会存在一些风险如果系统本身内存回收已经很紧张再去调大它极有可能触发OOM甚至引起系统宕机。所以在调大的时候一定要先做一些检查看看此时是否可以调整。
当然了如果你的sysstat版本较新并且内核版本较高那你也可以观察PSI记录的日志信息是否跟业务抖动相吻合。根据sar的这些信息我们可以推断出故障是否跟Page Cache相关。
既然是通过sar的日志信息来评判那么对日志信息的丰富度就有一定要求。你需要对常见的一些问题做一些归纳总结然后把这些常见问题相关联的指标记录在日志中供事后分析这样可以帮助你更加全面地分析问题尤其是发生频率较高的一些问题。
比如曾经我们的业务经常发生一些业务抖动在通过我们上述的分析手段分析出来是compation引起的问题后而且这类问题较多我们便把/proc/vmstat里compaction相关的指标我们在上面的表格里有写到具体是哪些指标记录到我们日志系统中。在业务再次出现抖动后我们就可以根据日志信息来判断是否跟compaction相关了。
## 课堂回顾
好了这节课我们就讲到这里我们简单回顾一下。这节课我们讲了Page Cache问题的分析方法论按照这个方法论我们几乎可以分析清楚Page Cache相关的所有问题而且也能帮助我们了解业务的内存访问模式从而帮助我们更好地对业务来做优化。
当然这套分析方法论不仅仅适用于Page Cache引发的问题对于系统其他层面引起的问题同样也适用。让我们再次回顾一下这些要点
* 在观察Page Cache的行为时你可以先从最简单易用的分析工具比如sar入手来得到一个概况然后再使用更加专业一些的工具比如tracepoint去做更细致的分析。这样你就能分析清楚Page Cache的详细行为以及它为什么会产生问题
* 对于很多的偶发性的问题往往需要采集很多的信息才能抓取出来问题现场这种场景下最好使用perf script来写一些自动化分析的工具来提升效率
* 如果你担心分析工具会对生产环境产生性能影响你可以把信息采集下来之后进行离线分析或者使用ebpf来进行自动过滤分析请注意ebpf需要高版本内核的支持。
这是我沉淀下来的定位问题的方法。也希望你在遇到问题时不逃避,刨根问底寻找根本原因是什么,相信你一定也会有自己的问题分析方法论,然后在出现问题时能够快速高效地找到原因。
## 课后作业
假设现在内存紧张, 有很多进程都在进行直接内存回收,如何统计出来都是哪些进程在进行直接内存回收呢?欢迎在留言区分享你的看法。
感谢你的阅读,如果你认为这节课的内容有收获,也欢迎把它分享给你的朋友,我们下一讲见。