使用perf-FlameGraph监控系统性能

使用perf-FlameGraph监控系统性能

背景

根据帕累托法则,只有优化处于性能瓶颈的那些少量代码,才能用最小的成本获得最大的收益。

单机系统中有一种最直接有效的方式,就是从代码层面直接寻找调用次数最频繁、耗时最长的函数,通常它就是性能瓶颈。但达到这个目标需要三个约束条件:

  1. 没有代码侵入性。比如,在函数执行的前后,分别打印一行日志记录时间,这当然能获取到函数的调用频次和执行时长,但并不可取,它的开发、维护成本太高了。
  2. 覆盖到代码中的全部函数。如果只是监控事先猜测的、有限的几个函数,往往会因为思维死角,遗漏掉真正的瓶颈函数。因此,只有监控所有函数的执行情况,并以一种全局的、直观的方式分析聚合后的监控结果,才能快速、准确地找到性能瓶颈。
  3. 搭建环境的成本足够低。最好使用现成的包,比如Brendan Gregg 发明的火焰图

关于火焰图的设计思路和详细使用方式,可以看他的论文:https://queue.acm.org/detail.cfm?id=2927301

FlameGraph

mysql

火焰图中最重要的信息,就是表示函数执行时间的 X 轴,以及表示函数调用栈的 Y 轴。函数方块的颜色是随机的,并没有特别的意义,只是为了在视觉上更容易区分开。

X 轴由多个方块组成,每个方块表示一个函数,其长度是定时采样得到的函数调用频率,因此可以简单粗暴地把它近似为执行时间。需要注意的是,如果函数 A 中调用了函数 B、C、D,监控采样时会形成 A->B、A->C、A->D 这 3 个函数调用栈,但火焰图会将 3 个调用栈中表示 A 函数的方块合并,并将 B、C、D 放在上一层中,并以字母表顺序排列它们。这样更有助于你找到耗时最长的函数。

Y 轴,它表示函数的调用栈。既可以看到内核 API 的函数调用栈,也可以看到用户态函数的调用栈

如何查看函数是否消耗过多CPU资源
  1. 首先,火焰图很容易从全局视角,通过寻找长方块,找到调用频率最高的几个函数。

  2. 函数方块长,有些是因为函数自身执行了很消耗 CPU 的代码,而有些则是调用的子函数耗时长造成的;如果函数方块的长度,远大于调用栈中子函数方块的长度之和,那么这个函数就执行了比较耗费 CPU 的计算。比如,下图中执行 TLS 握手的 ngx_ssl_handshake_handler 函数,自身并没有消耗 CPU 多少计算力。

    14c155f5ef577fa2aa6a127145b2acc2.jpg

    而更新 Nginx 时间的 ngx_time_update 函数就不同,它在做时间格式转换时消耗了许多 CPU,如下图所示:

    14c155f5ef577fa2aa6a127145b2acc2.jpg

使用perf-FlameGraph生成On CPU火焰图

该火焰图只能找到消耗 CPU 计算力最多的函数,因此它也叫做 On CPU 火焰图,由于 CPU 工作时会发热,所以色块都是暖色调。

# 安装
yum install perf
git clone --depth 1 https://github.com/brendangregg/FlameGraph.git

# 接着,针对运行中的进程 PID,使用 perf 采样函数的调用频率(对于 C/C++ 语言,为了能够显示完整的函数栈,你需要在编译时加入 -g 选项)
perf record -F 99 -p 进程PID -g --call-graph dwarf
或者全部进程
perf record -F 99 -a --call-graph dwarf
# 更多参数:https://www.brendangregg.com/perf.html

# 再将二进制信息转换为 ASCII 格式的文件,方便 FlameGraph 处理:
perf script > out.perf

# 再然后,需要汇聚函数调用栈,转化为 FlameGraph 生成火焰图的数据格式:
FlameGraph/stackcollapse-perf.pl out.perf > out.folded

# 最后一步,生成 SVG 格式的矢量图片:
FlameGraph/flamegraph.pl out.folded > out.svg



生成Off CPU 火焰图

有些使用了阻塞 API 的代码,则会导致进程休眠,On CPU 火焰图无法找到休眠时间最长的函数,此时可以使用 Off CPU 火焰图,它按照函数引发进程的休眠时间的长短,确定函数方块的长度。由于进程休眠时不使用 CPU,所以色块会使用冷色调。如下图所示:

详见:https://www.brendangregg.com/FlameGraphs/offcpuflamegraphs.html

赞赏
Nemo版权所有丨如未注明,均为原创丨本网站采用BY-NC-SA协议进行授权,转载请注明转自:https://nemo.cool/838.html

Nemo

文章作者

发表回复

textsms
account_circle
email

使用perf-FlameGraph监控系统性能
背景 根据帕累托法则,只有优化处于性能瓶颈的那些少量代码,才能用最小的成本获得最大的收益。 单机系统中有一种最直接有效的方式,就是从代码层面直接寻找调用次数最频繁、耗时最…
扫描二维码继续阅读
2022-02-09