在这篇博客文章中,我们将看到如何将性能(又名:性能_事件)与火焰图一起使用。它们用于生成我们选择的软件中调用的函数的图形表示。但是它可以扩展到您可以从中获取解析堆栈跟踪的任何软件。
在操作之前,请先确定不要在生产系统中运行这个,除非你知道带来的后果
安装所需的软件包
为了简单起见,我将在CentOS 7中使用命令,但是对于基于Debian的发行版(apt-get安装linux-tools-$(uname -r)而不是yum的命令是步骤中唯一的区别)。
要安装性能,只需发出:
SHELL> sudo yum install -y perf
要获取火焰图项目:
SHELL> mkdir -p ~/src
SHELL> cd ~/src
SHELL> git clone https://github.com/brendangregg/FlameGraph
就这样。我们可以走了。
捕获样本
火焰图是一种可视化数据的方法,所以我们需要一些样本作为基础。我们有三种方法可以做到这一点。(请注意,我们将使用-p标志仅从我们感兴趣的进程中捕获数据,但是如果需要,我们可以潜在地从所有正在运行的进程中捕获数据。)
1-仅捕获设定的时间量(此处为10秒):
SHELL> sudo perf record -a -F 99 -g -p $(pgrep -x mysqld) -- sleep 10
2-捕获,直到我们发送中断信号:
SHELL> sudo perf record -a -F 99 -g -p $(pgrep -x mysqld)
3-整个过程的捕获:
请注意,如果我们用这个变量中断,我们也将杀死产生的进程。壳
SHELL> sudo perf record -a -F 99 -g -- /sbin/mysqld \
--defaults-file=/etc/percona-server.conf.d/mysqld.cnf --user=mysql
或者
SHELL> sudo perf record -a -F 99 -g -p $(pgrep -x mysqld) -- mysql -e "SELECT * FROM db.table"
在第三种变体的第一种情况下,我们被迫从所有进程中捕获数据,因为不可能事先知道进程标识号(随着命令的执行,我们实际上正在启动MySQL服务)。当您希望从过程的确切开始就获得数据时,这种类型的命令非常有用,否则这是不可能的。
在第二个变体中,我们在已经运行的MySQL服务上运行一个查询,所以我们可以使用-p用于捕获服务器进程数据的标志。例如,如果您想在作业运行的确切时刻捕获数据,这很方便。
准备实践
初始捕获后,我们需要使收集的数据“可读”。这是必需的,因为它以二进制格式存储,由性能记录。为此,我们将使用:
SHELL> sudo perf script > perf.script
它会读作性能数据默认情况下,这是相同的默认情况性能记录用于其输出文件。它可以通过使用-我旗帜和o旗帜。
我们现在能够读取生成的文本文件,因为它是人类可读的形式。然而,当这样做的时候,你会很快意识到为什么我们需要把所有这些数据集合成一个更容易理解的形式。
生成火焰图
我们可以通过将第一行的输出作为第二行的输入,在一行中完成以下操作。因为我们没有添加火焰图git文件夹到我们的路径,我们将需要使用完整的路径。
SHELL> ~/src/FlameGraph/stackcollapse-perf.pl perf.script | ~/src/FlameGraph/flamegraph.pl > flamegraph.svg
我们现在可以打开。svg文件,并开始分析信息丰富的图表。
看起来怎么样?
作为一个例子,我将留下完整的命令、它们的输出以及使用数据捕获方法#2的过程生成的火焰图的截屏。我们将运行一个插入…选择查询数据库,这样我们就可以分析它的执行情况。
SHELL> time sudo perf record -a -F 99 -g \
-p $(pgrep -x mysqld) \
-- mysql test -e "INSERT INTO joinit SELECT NULL, uuid(), time(now()), (FLOOR( 1 + RAND( ) *60 )) FROM joinit;"
Warning:
PID/TID switch overriding SYSTEM
[ perf record: Woken up 7 times to write data ]
[ perf record: Captured and wrote 1.909 MB perf.data (8214 samples) ]
real 1m24.366s
user 0m0.133s
sys 0m0.378s
SHELL> sudo perf script | \
~/src/FlameGraph/stackcollapse-perf.pl perf.script | \
~/src/FlameGraph/flamegraph.pl > mysql_select_into_flamegraph.svg
敏锐的读者会注意到,我们在这里走得更远,通过管道(|)避免读写perf.script输出文件。此外,还有时间输出,这样我们就可以估计工具生成的数据量(大约2Mb,1分25秒);当然,这将因多种因素而异,所以要谨慎对待,并在自己的环境中进行测试。
生成的火焰图是:

优化的一个明显的候选方法是write_record:如果我们能让这个函数更快,那么就有很大的潜力减少总的执行时间(左下角蓝色的平方,我们可以看到总共约60%的样本是在这个代码路径中获取的)。在下面的最后一节,我们链接到一篇博客文章,详细解释了如何解释火焰图,但是现在,知道你可以将鼠标放在函数名上,它会动态地改变左下角显示的信息。有了以下指南,您也可以更好地可视化它:

结论
对于支持团队来说,我们在许多情况下使用这个过程,我们需要对MySQL正在执行什么以及执行多长时间有一个深入的了解。这样,我们可以更好地了解特定工作负载背后的操作,并据此采取行动。该程序可用于优化或故障排除,是我们工具带中非常强大的工具!众所周知,人类更擅长处理图像而不是文本,在我看来,这个工具很好地利用了这一点。




