火焰图(FlameGraph)的简单学习


=Start=

缘由:

最近在对内部一些项目做性能压测的过程中简单接触了一下「火焰图」的概念。这里简单记录一下,方便以后快速参考。

正文:

参考解答:
# 火焰图是什么?

火焰图 是基于 perf命令结果 产生的 SVG图片,用来展示 CPU 的调用栈。

# 火焰图怎么看?
  • Y轴 表示 调用栈,每一层都是一个函数。调用栈越深,火焰就越高,顶部就是正在执行的函数,下方都是它的父函数;
  • X轴 表示 抽样数如果一个函数在 X轴 占据的宽度越宽,就表示它被抽到的次数越多,即执行的时间长。

火焰图里面的颜色是随机选取的,并没有特殊含义。

火焰图主要就是看顶层的哪个函数占据的宽度最大。只要有”平顶”(plateaus),就表示该函数可能存在性能问题。

# 如何生成火焰图?

下面以一个简单的C程序为例,介绍一下火焰图的生成流程:

# 终端一

0、编辑、编译、链接,准备解析工具/脚本
vim test.c
gcc test.c -o test.out
git clone https://github.com/brendangregg/FlameGraph

1、启动执行
./test.out

# 终端二

2、用 `perf record` 命令来采集数据
[sudo] perf record -p $(pgrep test.out) -F 999 -a -g -- sleep 20

选项释义:
-p 用于指定要采集的具体进程pid;
-F 用于指定采样频率为 999Hz(每秒999次) ,如果 999次 都返回同一个函数名,那就说明 CPU 这一秒钟都在执行同一个函数,可能存在性能问题;
-a 用于表示从所有CPU中进行采集;
-g 用于表示记录调用栈;
sleep 20 用于指定持续采集20秒;
-e 用于指定采集事件,如果没有则默认采集cycles(即 CPU clock 周期);

补充说明:
上面的 perf record 命令执行完成后,会在当前的目录下生成 perf.data 文件。

3、用 `perf script` 命令解析(perf.data文件)数据以生成堆栈信息
perf script > out.stack

4、折叠堆栈
./FlameGraph/stackcollapse-perf.pl out.stack > out.folded

5、生成 svg 图
./FlameGraph/flamegraph.pl out.folded > test.svg

# 在浏览器中进行查看该 svg 文件

&

#include <stdio.h>
#include <unistd.h>

int a1() { // 3w empty loops
    int i = 0;
    for(; i < 30000; i++) {};
}

int a2() { // 2w empty loops
    int i = 0;
    for(; i < 20000; i++) {};
}


int a() { // 50w empty loops
    int i = 0;
    for(; i < 10; i++) {
        a1();
        a2();
    };
}

int b() { // 20w empty loops
    int i = 0;
    for(; i < 200000; ++i) {};
}

int c() {
    sleep(1);
}

int d() { // 30w empty loops
    int i = 0;
    for(; i < 300000; ++i) {};
}

void test() {
    a();
    b();
    c();
    d();
}


int main() {
    while(1) test();
    return 0;
}

 

参考链接:

=END=


《 “火焰图(FlameGraph)的简单学习” 》 有 5 条评论

  1. 全链路压测平台(Quake)在美团中的实践
    https://mp.weixin.qq.com/s/7kKhAYtkIuvlBnZlaYATnw
    `
    压测的作用:
    验证峰值流量下服务的稳定性和伸缩性。
    验证新上线功能的稳定性。
    进行降级、报警等故障演练。
    对线上服务进行更准确的容量评估。
    ……

    全链路压测是基于线上真实环境和实际业务场景,通过模拟海量的用户请求,来对整个系统进行压力测试。早期,我们在没有全链路压测的情况下,主要的压测方式有:
    · 对线上的单机或集群发起服务调用。
    · 将线上流量进行录制,然后在单台机器上进行回放。
    · 通过修改权重的方式进行引流压测。

    但以上方式很难全面的对整个服务集群进行压测,如果以局部结果推算整个集群的健康状况,往往会“以偏概全”,无法评估整个系统的真实性能水平,主要的原因包括:
    · 只关注涉及的核心系统,无法覆盖到所有的环节。
    · 系统之间都是通过一些基础服务进行串联,如 Nginx、Redis 缓存、数据库、磁盘、网络等等,而基础服务问题在单机压测中往往不能被暴露出来。

    自研解决方案要具备的能力:
    提供模拟线上真实流量的能力
    具备快速创建压测环境的能力
    支持多种压测类型
    提供压测过程的实时监控与过载保护
    `

  2. 用CPI火焰图分析Linux性能问题
    https://mp.weixin.qq.com/s/k5Iz2yE5iYrbuD3Gjf2NEg
    `
    在计算机体系结构领域,经常可以看到 CPI 的使用。CPI 即 Cycle Per Instruction 的缩写,它的含义就是每指令周期数。此外,在一些场合,也可以经常看到 IPC,即 Instruction Per Cycle,含义为每周期指令数。
    因此不难得出,CPI 和 IPC 的关系为:
    CPI = 1 / IPC
    `

  3. 压测工具如何选择? ab、locust、Jmeter、go压测工具【单台机器100w连接压测实战】
    https://mp.weixin.qq.com/s/1AGEIz1rl_Dv0QslhRAU4w
    `
    1、项目说明
    1.1 go-stress-testing
    1.2 项目体验

    2、压测
    2.3.1 压测类型解释
    2.3.2 压测名词解释
    2.3.3 机器性能指标解释
    2.3.4 访问指标解释
    2.1 压测是什么
    2.2 为什么要压测
    2.3 压测名词解释
    3.4 如何计算压测指标

    3、常见的压测工具
    3.4.1 云压测介绍
    3.4.2 阿里云 性能测试 PTS
    3.4.3 腾讯云 压测大师 LM
    3.1 ab
    3.2 locust
    3.3 Jmeter
    3.4 云压测

    4、go-stress-testing go语言实现的压测工具
    4.1 介绍
    4.2 用法
    4.3 实现
    4.4 go-stress-testing 对 Golang web 压测

    5、压测工具的比较
    5.1 比较
    5.2 如何选择压测工具

    6、单台机器100w连接压测实战
    6.1 说明
    6.2 内核优化
    6.3 客户端配置
    6.4 准备
    6.5 压测数据

    7、总结
    8、参考文献
    `

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注