初识火焰图

作者: 印随2018 | 来源:发表于2017-04-25 16:35 被阅读148次
火焰图就像是给一个软件系统拍的 X 光照片,
可以很自然地把时间和空间两个维度上的信息融合在一张图上,
以非常直观的形式展现出来,
从而反映系统在性能方面的很多定量的统计规律。

扩展:章亦春 《动态追踪技术漫谈》

什么是火焰图

火焰图只是一种统计数据的展现方式,它和直方图、曲线图没有什么本质的区别。最经典的火焰图是统计某一个软件的所有代码路径在 CPU 上面的时间分布。

下面是redis-server的火线图


imgimg

火焰图中展示的是什么数据

拿上图为例,图中展示的就是Redis-server运行时的部分代码路径,每个方块代表一个函数调用,水平方向代表CPU耗时占比,垂直方向代表函数的调用关系,实际上,这张图就是redis-server进程一段时间内的栈快照的聚合。

注意:图中没有任何关于时间的信息,它只是进程运行过程中各个函数的时间占比。

怎样生成火焰图(On-CPU)

  1. 周期性的采集栈数据
    可选的工具
    • systemtap
    • perf
    • 其他(不同编程语言,不同的系统架构)
  2. 以栈为维度,做聚合统计
    Brendan Gregg 大大已经提供
  3. 生成火线图(svg)
    Brendan Gregg 大大已经提供

可见,这里有两个难点

  • 获取栈数据
  • 解释栈数据

使用systemtap采集栈数据

systemtap脚本

probe begin {
    warn(sprintf("Tracing %d (/root/redis-3.2.8/src/redis-server) in user-space only...\n", target()))
}


global bts;
global quit = 0;

probe timer.profile {
    if (pid() == target()) {
        if (!quit) {
            bts[ubacktrace()] <<< 1;

        } else {

            foreach (bt in bts- limit 1024) {
                print_ustack(bt);
                printf("\t%d\n", @count(bts[bt]));
            }

            exit()
        }
    }
}

probe timer.s(5) {
    nstacks = 0
    foreach (bt in bts limit 1) {
        nstacks++
    }

    if (nstacks == 0) {
        warn("No backtraces found. Quitting now...\n")
        exit()

    } else {
        warn("Time's up. Quitting now...(it may take a while)\n")
        quit = 1
    }
}

脚本中,使用了两个定时器,一个定时器负责周期性的采集栈数据,另一个定时器是结束脚本,并触发输出采集数据。

采样数据

下面就是systemtap脚本输出(redis-server的栈数据)

 0x7f96f75e8c3d : __open_nocancel+0x24/0x57 [/usr/lib64/libpthread-2.17.so]
 0x42cd9d : zmalloc_get_rss+0x58/0x159 [/root/redis-3.2.8/src/redis-server]
 0x422a15 : serverCron+0xff/0x84c [/root/redis-3.2.8/src/redis-server]
 0x41d394 : processTimeEvents+0x1a1/0x1ff [/root/redis-3.2.8/src/redis-server]
 0x41d6b7 : aeProcessEvents+0x2c5/0x2cd [/root/redis-3.2.8/src/redis-server]
 0x41d7d0 : aeMain+0x48/0x55 [/root/redis-3.2.8/src/redis-server]
 0x429f3a : main+0x6ec/0x707 [/root/redis-3.2.8/src/redis-server]
 0x7f96f723ab35 : __libc_start_main+0xf5/0x1c0 [/usr/lib64/libc-2.17.so]
 0x4192a9 : _start+0x29/0x30 [/root/redis-3.2.8/src/redis-server]
    1
 0x7f96f7310d13 : __epoll_wait_nocancel+0x2a/0x57 [/usr/lib64/libc-2.17.so]
 0x41c9d6 : aeApiPoll+0x85/0x15f [/root/redis-3.2.8/src/redis-server]
 0x41d59c : aeProcessEvents+0x1aa/0x2cd [/root/redis-3.2.8/src/redis-server]
 0x41d7d0 : aeMain+0x48/0x55 [/root/redis-3.2.8/src/redis-server]
 0x429f3a : main+0x6ec/0x707 [/root/redis-3.2.8/src/redis-server]
 0x7f96f723ab35 : __libc_start_main+0xf5/0x1c0 [/usr/lib64/libc-2.17.so]
 0x4192a9 : _start+0x29/0x30 [/root/redis-3.2.8/src/redis-server]
    1
 0x7f96f75e849d : __read_nocancel+0x24/0x57 [/usr/lib64/libpthread-2.17.so]
 0x42cdc9 : zmalloc_get_rss+0x84/0x159 [/root/redis-3.2.8/src/redis-server]
 0x422a15 : serverCron+0xff/0x84c [/root/redis-3.2.8/src/redis-server]
 0x41d394 : processTimeEvents+0x1a1/0x1ff [/root/redis-3.2.8/src/redis-server]
 0x41d6b7 : aeProcessEvents+0x2c5/0x2cd [/root/redis-3.2.8/src/redis-server]
 0x41d7d0 : aeMain+0x48/0x55 [/root/redis-3.2.8/src/redis-server]
 0x429f3a : main+0x6ec/0x707 [/root/redis-3.2.8/src/redis-server]
 0x7f96f723ab35 : __libc_start_main+0xf5/0x1c0 [/usr/lib64/libc-2.17.so]
 0x4192a9 : _start+0x29/0x30 [/root/redis-3.2.8/src/redis-server]
    1

这是其中一种栈数据的输出格式,Brendan Gregg大大的工具可以支持好几种输出格式,有兴趣可以查看源码。

聚合采样数据

_start;__libc_start_main;main;aeMain;aeProcessEvents;aeApiPoll;__epoll_wait_nocancel 1
_start;__libc_start_main;main;aeMain;aeProcessEvents;processTimeEvents;serverCron;zmalloc_get_rss;__open_nocancel 1
_start;__libc_start_main;main;aeMain;aeProcessEvents;processTimeEvents;serverCron;zmalloc_get_rss;__read_nocancel 1

小结

由于systemtap安装较为繁琐,因此本文作者开发了一个shell脚本,使用perf完成以上步骤。
源码

生成一个火焰图很容易,难的是从火焰图中发现问题,并且能够给出较为合理的解释,再进一步给出优化方案。

相关文章

  • 初识火焰图

    扩展:章亦春 《动态追踪技术漫谈》 什么是火焰图 火焰图只是一种统计数据的展现方式,它和直方图、曲线图没有什么本质...

  • erlang火焰图

    erlang火焰图 目录 火焰图相关什么是火焰图火焰图的意义 erlang火焰图如何绘制erlang火焰图erla...

  • 火焰图

    首先用 perf script 工具对 perf.data 进行解析 将解析出来的信息存下来, 供生成火焰图,首先...

  • 火焰图

    火焰图是性能分析的一大利器。可以抓取某个进程在一段时间内的函数调用栈的分布情况,从而知道哪些函数执行时间过长。 火...

  • Java 火焰图

    火焰图是进行性能分析的工具,可以通过Flame Graph获取指定程序的火焰图,目前IDEA也增添了火焰图功能,叫...

  • 【性能优化】火焰图实战

    1 火焰图介绍 性能调优利器:火焰图[https://www.infoq.cn/article/a8kmnxdhb...

  • 白话火焰图

    转自:https://huoding.com/2016/08/18/531 很多人感冒发烧的时候,往往会模仿神农氏...

  • 火焰图生成

    上篇介绍了systemtap的使用。承接上篇,这篇接着纪录后续,用systemtap统计了信息,如何更加直观的观察...

  • Java 火焰图

    原文:https://medium.com/netflix-techblog/java-in-flames-e76...

  • 火焰图实践

    1. 场景描述: 因为生产环境组件服务进程执行缓慢导致部分资源无法释放,进而引起了各种任务超时。研究源码发现,部分...

网友评论

本文标题:初识火焰图

本文链接:https://www.haomeiwen.com/subject/gdvvzttx.html