写点什么

TiDB 性能分析工具——PProf

  • 2022 年 7 月 11 日
  • 本文字数:2758 字

    阅读完需:约 9 分钟

作者: alexshen 原文来源:https://tidb.net/blog/2a74d783


【是否原创】是


【首发渠道】TiDB 社区


【正文】

背景

数据库的性能永远是数据库开发过程中最为关注的问题,所以在 TiDB 开发过程中,要经常对数据库性能进行测试,在完成功能的基础上保证性能的稳定,如果性能出现明显波动和大幅度下降,则需要定位造成性能下降的原因,同样的,当需要去优化数据库性能,定位性能瓶颈时,也需要定位到具体的方法进行优化。那么这个过程中,我们如何进行性能分析,迅速的定位到问题方法,就可以使用到 Profiling 工具了。


Profiling 工具,是一种性能分析工具,可以跟踪程序在运行中的方法调用栈,并统计相关的资源开销和时间消耗,例如 CPU,内存等资源,通过分析方法与方法之间的调用关系和资源开销可以帮助我们迅速的定位到资源消耗最大的方法,快速找到问题的关键。


当然 TiDB 本身进行分析的手段比较多,内置各种监控,但是在本地源码开发的过程中,可以推荐使用 Profiling 工具,一是启用这种工具非常简单,不需要过多的操作,二是 Profiling 的指标比较齐全,监控更为细致,分析起来非常方便。

TiDB 中启用 Profiling 工具

不同语言都有自己的 Profiling 工具,TiDB 是使用 Golang 实现的,所以可以直接使用 Golang 的 Profiling 工具来进行分析,那么这里本文选择的是 PProf。


PProf 是 Golang 提供的代码性能分析工具,可以直接生成代码分析报告,可以采用命令式交互进行查看,也可以进行可视化展示。这里不做过多介绍,直接看下如何将 PProf 引入到 TiDB 中。

引用 pprof 包

PProf 包有两种:


  1. 服务型应用 _ “net/http/pprof” 包,专用于采集 web 服务运行数据的分析

  2. 工具型应用 “runtime/pprof” 包,专用于采集应用程序运行数据的分析

  3. 数据库本身是一种服务型应用,需要对外暴露服务,所以选择”net/http/pprof”包。

  4. 程序中引入 net/http/pprof 包,可以直接在主程序的最前面加上调用语句,只需要一句话就能启动 PProf,十分方便。如下:

  5. Code: PProf



所以在 TiDB 中,先找到主程序入口,tidb/tidb-server/main.go 中的 main() 方法,插入三行代码,会自动引入 PProf 包,然后正常启动即可。


通过 Web 界面查看

成功启动程序后,可以直接访问:http://host:8005/debug/pprof/ 来查看



其中有很多的子文件可以打开,下面也有相应的介绍:


allocs : 过去所有内存分配的样例


block : 导致阻塞同步的堆栈跟踪


cmdline : 当前程序的命令行调用


goroutine : 当前所有 goroutine 的堆栈跟踪


heap : 活动对象的内存分配情况,可以指定 gc Get 参数,以便在获取堆样本之前运行 gc


mutex : 互斥锁竞争者的堆栈跟踪


profile : CPU 配置文件。您可以在 seconds GET 参数中指定持续时间,获取配置文件后,使用 go tool pprof 命令来查看配置文件。


threadcreate : 导致创建新 OS 线程的堆栈跟踪


trace : 跟踪当前程序的执行。您可以在 seconds GET 参数中指定持续时间。获取跟踪文件后,使用 go tool trace 命令来调查跟踪。


可以看到 PProf 进行跟踪和监控的指标非常多,除了常用的 CPU,内存开销,还包括线程,goruntine,互斥锁等堆栈跟踪,一般在普通的性能分析中是用不到这么多指标的,但是针对于不同的场景和需求,大家可以自己选择并进行查看。

使用交互式命令行查看

如果我们想要观察一段时间内程序各个指标的值,可以输入以下指令:


go tool pprof http://host:8005/debug/pprof/profile?seconds=60



执行该命令后等待 60s 即可进入到交互式命令模式(后面的 profile 可以换成其他的参数,例如 heap,mutex 等等,seconds 表示所要观察的时间。)


进入交互式命令模式后可以输入一系列指令进行详细的记录查看,例如 Top10 查看耗时最长的前 10 个记录,其余的指令可以通过 pprof help 来查看详情,这里不一一介绍。



flat : 给定函数上的运行耗时


flat% : 同上的 CPU 运行耗时的总比例


sum% : 给定函数累计使用 CPU 总比例


cum ; 当前函数加上它之上的调用运行总耗时


cum% : 同上的 CPU 运行耗时总比例


最后一列 : 函数名

通过 web 指令查看可视化界面

如果想要查看图形化界面,则需要安装 Graphviz


sudo apt-get install graphviz


安装 Graphviz 后,在交互命令行中输入 web 即可,可以通过可视化图形来查看方法之间的调用关系和每一个方法的资源开销与时耗。



其中每一个方块都代表一个方法,方法之间就是调用关系,方块大小则表示该方法的资源开销和时耗越大,所以通过每一个方块大小和内容,可以很快的定位到资源消耗较大的方法或者是异常的方法。


其实通过这种方式,在初学 TiDB 源码的时候,可以查看这种关系图,来迅速学习 TiDB 的代码架构,方法调用流程和功能,还 0 包括关键函数位置,非常适合新手进行源码学习。


除了这种流程图式的可视化展示,还有一种可视化展示 - 火焰图。

使用 go-torch 工具生成火焰图

go-torch 是 uber 开源的一个工具,可以直接读取 pprof 的 profiling 数据,生成一个火焰图 svg 的文件,通过浏览器即可打开,查看整个火焰图(该图为可交互的)


地址:GitHub - uber-archive/go-torch: Stochastic flame graph profiler for Go programs

安装 go-torch 和 FlameGraph

go get github.com/uber/go-torch


cd $GOPATH/src/github.com/uber/go-torch


git clone https://github.com/brendangregg/FlameGraph.git


cp FlameGraph/flamegraph.pl /usr/local/bin




注意: 这里直接尝试一下 go-torch 命令,如果报错 command not found 则需要自己编译


cd $GOPATH/src/github.com/uber/go-torch


go build —– 生成可执行文件


cp go-torch /usr/local/bin



使用 go-torch 生成 svg 文件

go-torch 的具体指令可以通过 go-torch -h 来查看


go-torch -u http://host:8005 -t 60 -f cpu.svg



-u 指定相关 url 当没有后缀的时候 默认为 http://localhost:8080/debug/pprof/profile


-t 指定监控的时间为 60s


-f 指定文件名,当前目录下生成 cpu.svg

查看火焰图

当生成 svg 文件后,我们可以直接将其用浏览器打开(将文件拖到浏览器里面)


火焰图调用顺序从下往上,宽度代表其占用的时间,由于火焰图是可交互的,可以用鼠标点击每一个小方块进去看其具体的信息和其内部函数的调用。



由于 TiDB 整个系统较为庞大,文章篇幅有限,本文并没有过多介绍的 PProf 分析 TiDB 的过程和结果,只是介绍了如何使用 PProf,那么大家可以在了解后,本地进行操作和分析,方便大家进行 TiDB 的开发。

总结

  1. 通过 PProf 工具可以查看一段时间内 TiDB 中每个函数的资源占用率,最快的速度找到开销异常的函数并进行定位,找到性能问题的原因。

  2. 可以将多个版本的 TiDB(开发前和开发后)进行性能分析,通过 Profiling 工具生成的图进行直接对比,可以更直观的发现改动代码对于每个模块造成的影响和两个版本的差异。

  3. 通过函数调用关系图,可以帮我们更快的了解 TiDB 代码结构和方法调用栈,适合新手学习,寻找关键函数。


发布于: 刚刚阅读数: 2
用户头像

TiDB 社区官网:https://tidb.net/ 2021.12.15 加入

TiDB 社区干货传送门是由 TiDB 社区中布道师组委会自发组织的 TiDB 社区优质内容对外宣布的栏目,旨在加深 TiDBer 之间的交流和学习。一起构建有爱、互助、共创共建的 TiDB 社区 https://tidb.net/

评论

发布
暂无评论
TiDB 性能分析工具——PProf_TiDB 底层架构_TiDB 社区干货传送门_InfoQ写作社区