前面几篇文章,我们讲了 Page Cache 的一些基础知识,以及如何去处理 Page Cache 引发的一些问题。今天我们来讲讲,如何判断问题是不是由 Page Cache 引起的。 我们知道,一个问题往往牵扯到操作系统的很多模块,比如说,当系统出现 load 飙高的问题时,可能是 Page Cache 引起的,也可能是锁冲突太厉害,物理资源(CPU、内存、磁 盘 I/O、网络 I/O)有争抢导致的;也可能是内核特性设计缺陷导致的,等等。 如果没有找到问题根源而贸然行动,务必会引起其他更多问题,比如说,load 飙高原本是 Page Cache 引起的,而你误以为是网络引起的,然后对网络进行限流,看起来问题暂时解决了,但系统运行久了还是会出现 load 飙高情况,治标不治本。那么当问题发生时,我们如何判断它是不是由 Page Cache 引起的呢?
Linux系统下问题甄别典型手段
Linux 内核主要是通过 /proc 和 /sys把系统信息导出给用户, 当不清楚问题发生的原因时,可以先试着去这些目录读取下系统信息,看看哪些指标异常。比如,当查明问题是否由 Page Cache 引起时,可以先去读取/proc/vmstat 里面的信息,看哪些指标单位时间内变化较大。如果 pgscan 相关指标变化较大,那就可能是 Page Cache 引起的,因为 pgscan 代表了 Page Cache 的内存回收行为,它变化较大往往意味着系统内存压力很紧张。下图显示了Linux系统展示给用户空间的常见文件:
/proc 和 /sys 里面的信息可以给我们指出一个问题分析的大致方向,我们可以判断出问题 是不是由 Page Cache 引起的,但是如果想要深入地分析问题,知道 Page Cache 是如何 引起问题的,我们还需要掌握更加专业的分析手段,专业的分析工具有 ftrace,ebpf, perf 等。为了让你在遇到问题时更加方便地找到合适的分析工具,我借用Bredan Gregg 的一张 图,并根据自己的经验,把这张图略作了一些改进,帮助你学习该如何使用这些分析工 具:
这张图整体上分为静态追踪(预置了追踪点)和动态追踪(需要借助 probe):如果你想要追踪的东西已经有了预置的追踪点,那你直接使用这些预置追踪点就可以了; 如果没有预置追踪点,那你就要看看是否可以使用 probe(包括 kprobe 和 uprobe) 来实现。
因为分析工具自身也会对业务造成一些影响(Heisenbug),比如说使用 strace 会阻塞进程的运行,再比如使用 systemtap 也会有加载编译的开销等,所以我们在使用这些工具之 前也需要去详细了解下这些工具的副作用,以免引起意料之外的问题。
接下来我们一起分析两个具体问题。
现在系统load 很高,是由 Page Cache 引起的吗?
-
场景:业务一直稳定运行着,忽然出现很大的性能抖动或较高的 load 值,那怎么判断是不是由 Page Cache 引起的呢?
-
分析:
-
对于 Page Cahe 相关的问题,推荐使用 sar 来采集 Page Cache 的概况,它是系统默认配置好的工具,简单方便。比如通过
sar -B来分析分页信息 (Paging statistics), 以及sar -r来分析内存使用情况统计 (Memory utilization statistics) 等。重点观察 sar 里面记录的 PSI(Pressure-Stall Information)信息来查看 Page Cache 产生压力情况,尤其是给业务产生的压力,而这些压力最终都会体现在 load 上。比如 PSI 中表示内存压力的如下输出:some avg10=45.49 avg60=10.23 avg300=5.41 total=76464318 full avg10=40.87 avg60=9.05 avg300=4.29 total=58141082avg10 表示最近 10s 内存的平均压力情况,如果它很大(比如 大于 40)那 load 飙高大概率是由于内存压力,尤其是 Page Cache 的压力引起的。
-
进一步获取更多Page Cache相关指标。因为 sar 采集的只是一些常用的指标,它并没有覆盖 Page Cache 的所有行为,比如说内 存规整(memory compaction)、业务 workingset 等这些容易引起 load 飙高的问题 点。在我们想要分析更加具体的原因时,就需要去采集这些指标了。通常在 Page Cache 出问题时,这些指标中的一个或多个都会有异常,这里我给你列出一些常见指标:
采集完这些指标后,我们就可以分析 Page Cache 异常是由什么引起的了。比如当我们发现,单位时间内 compact_fail 变化很大时,那往往意味着系统内存碎片很严重,已经很难申请到连续物理内存了,这时你就需要去调整碎片指数或者手动触发内存规整,来减 缓因为内存碎片引起的压力了。
-
利用内核预置的相关 tracepoint 来做更加细致的分析。前面采集的数据指标,可以帮助我们来定位到问题点究竟是什么,但是有的时候,我们还需要知道是什么东西在进行连续内存的申请,从而来做更加有针对性的调整,这就需要进行进一步观察内核预置的相关 tracepoint 了。
下面继续以内存规整 (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 这个进程触发了 compaction,begin 和 end 这两个 tracepoint 触发的时间戳相减,就可以得到 compaction 给业务带来的延迟。很多时候由于采集的信息量太大,我们往往需要借助一些自动化分析的工具来分析,这样 会很高效。
-
昨天系统 load 很高,是由 Page Cache 引起的吗?
对于过去发生的问题,只能查看历史记录,我们可以根据 sar 的日志信息来判断当时发生了什么事情。当然了,如果你的 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 需要高版本内核的支持。
这是我沉淀下来的定位问题的方法。也希望你在遇到问题时不逃避,刨根问底寻找根本原因是什么,相信你一定也会有自己的问题分析方法论,然后在出现问题时能够快速高效地 找到原因。
关注我,不迷路。更多嵌入式Linux精品文章关注公众号【细说嵌入式】