性能优化工具

性能优化工具

perf

alt
https://www.brendangregg.com/perf.html

火焰图

alt

火焰图有以下特征(这里以 on-cpu 火焰图为例):

每一列代表一个调用栈,每一个格子代表一个函数

纵轴展示了栈的深度,按照调用关系从下到上排列。最顶上格子代表采样时,正在占用 cpu 的函数。

横轴的意义是指:火焰图将采集的多个调用栈信息,通过按字母横向排序的方式将众多信息聚合在一起。需要注意的是它并不代表时间。

横轴格子的宽度代表其在采样中出现频率,所以一个格子的宽度越大,说明它是瓶颈原因的可能性就越大。

火焰图格子的颜色是随机的暖色调,方便区分各个调用信息。

其他的采样方式也可以使用火焰图, on-cpu 火焰图横轴是指 cpu 占用时间,off-cpu 火焰图横轴则代表阻塞时间。

采样可以是单线程、多线程、多进程甚至是多 host,进阶用法可以参考附录进阶阅读

火焰图类型

常见的火焰图类型有 On-CPU,Off-CPU,还有 Memory,Hot/Cold,Differential 等等。他们分别适合处理什么样的问题呢?

这里笔者主要使用到的是 On-CPU、Off-CPU 以及 Memory 火焰图,所以这里仅仅对这三种火焰图作比较,也欢迎大家补充和斧正。 alt

如何绘制火焰图?

要生成火焰图,必须要有一个顺手的动态追踪工具,如果操作系统是 Linux 的话,那么通常通常是 perf 或者 systemtap 中的一种。其中 perf 相对更常用,多数 Linux 都包含了 perf 这个工具,可以直接使用;SystemTap 则功能更为强大,监控也更为灵活。网上关于如何使用 perf 绘制火焰图的文章非常多而且丰富,所以本文将以 SystemTap 为例。

SystemTap 是动态追踪工具,它通过探针机制,来采集内核或者应用程序的运行信息,从而可以不用修改内核和应用程序的代码,就获得丰富的信息,帮你分析、定位想要排查的问题。SystemTap 定义了一种类似的 DSL 脚本语言,方便用户根据需要自由扩展。不过,不同于动态追踪的鼻祖 DTrace ,SystemTap 并没有常驻内核的运行时,它需要先把脚本编译为内核模块,然后再插入到内核中执行。这也导致 SystemTap 启动比较缓慢,并且依赖于完整的调试符号表。

使用 SystemTap 绘制火焰图的主要流程如下:

安装 SystemTap 以及 操作系统符号调试表
根据自己所需绘制的火焰图类型以及进程类型选择合适的脚本
生成内核模块
运行 SystemTap 或者运行生成的内核模块统计数据
将统计数据转换成火焰图
本文演示步骤将会基于操作系统 Tlinux 2.2

用 perf 生成火焰图

1 perf 采集数据

让我们从 perf 命令(performance 的缩写)讲起, 它是 Linux 系统原生提供的性能分析工具, 会返回 CPU 正在执行的函数名以及调用栈(stack)

sudo perf record -F 99 -p 3887 -g -- sleep 30

perf record 表示采集系统事件, 没有使用 -e 指定采集事件, 则默认采集 cycles(即 CPU clock 周期), -F 99 表示每秒 99 次, -p 13204 是进程号, 即对哪个进程进行分析, -g 表示记录调用栈, sleep 30 则是持续 30 秒.

-F 指定采样频率为 99Hz(每秒99次), 如果 99次 都返回同一个函数名, 那就说明 CPU 这一秒钟都在执行同一个函数, 可能存在性能问题.

运行后会产生一个庞大的文本文件. 如果一台服务器有 16 个 CPU, 每秒抽样 99 次, 持续 30 秒, 就得到 47,520 个调用栈, 长达几十万甚至上百万行.

为了便于阅读, perf record 命令可以统计每个调用栈出现的百分比, 然后从高到低排列.

sudo perf report -n --stdio

alt 2 生成火焰图

首先用 perf script 工具对 perf.data 进行解析

# 生成折叠后的调用栈
perf script -i perf.data &> perf.unfold

将解析出来的信息存下来, 供生成火焰图

首先用 stackcollapse-perf.pl 将 perf 解析出的内容 perf.unfold 中的符号进行折叠 :

# 生成火焰图
./stackcollapse-perf.pl perf.unfold &> perf.folded

# 最后生成 svg 图
./flamegraph.pl perf.folded > perf.svg

我们可以使用管道将上面的流程简化为一条命令

perf script | FlameGraph/stackcollapse-perf.pl | FlameGraph/flamegraph.pl > process.svg
alt
参考资料:https://zhuanlan.zhihu.com/p/138502887

安装 SystemTap 以及 操作系统符号调试表

使用 yum 工具安装 systemtap:

yum install systemtap systemtap-runtime

由于 systemtap 工具依赖于完整的调试符号表,而且生产环境不同机器的内核版本不同(虽然都是Tlinux 2.2版本,但是内核版本后面的小版本不一样,可以通过 uname -a 命令查看)所以我们还需要安装 kernel-debuginfo 包、 kernel-devel 包 我这里是安装了这两个依赖包

kernel-devel-3.10.107-1-tlinux2-0046.x86_64
kernel-debuginfo-3.10.107-1-tlinux2-0046.x86_64

根据自己所需绘制的火焰图类型以及进程类型选择合适的脚本 使用 SystemTap 统计相关数据往往需要自己依照它的语法,编写脚本,具有一定门槛。幸运的是,github 上春哥(agentzh)开源了两组他常用的 SystemTap 脚本:openresty-systemtap-toolkit 和 stapxx,这两个工具集能够覆盖大部分 C 进程、nginx 进程以及 Openresty 进程的性能问题场景。

https://link.zhihu.com/?target=https%3A//github.com/openresty/openresty-systemtap-toolkit

https://link.zhihu.com/?target=https%3A//github.com/openresty/stapxx

我们这里需要绘制 off-cpu 火焰图,所以使用 sample-bt-off-cpu 脚本即可

生成内核模块

现在我们有了统计脚本,也安装好了 systemtap,正常来说就可以使用了,但由于 systemtap 是通过生成内核模块的方式统计相关探针的统计数据,而 tlinux 要求所有运行的内核模块需要先到 tlinux 平台签名才可以运行,所以:

故需要先修改 off-cpu 脚本,让其先生成内核模块;之后对该内核模块作签名;最后使用 systemtap 命令手工运行该脚本,统计监控数据

Systemtap 执行流程如下: alt

parse:分析脚本语法
elaborate:展开脚本 中定义的探针和连接预定义脚本库,分析内核和内核模块的调试信息
translate:.将脚本编译成c语言内核模块文件放 在$HOME/xxx.c 缓存起来,避免同一脚本多次编译
build:将c语言模块文件编译成.ko的内核模块,也缓存起来。
把模块交给staprun,staprun加载内核模块到内核空间,stapio连接内核模块和用户空间,提供交互IO通道,采集数据。

所以我们这里修改下 off-cpu 的 stap 脚本,让其只运行完第四阶段,只生成一个内核模块

// 在 stap 命令后增加 -p4 参数,告诉systemtap,当前只需要执行到第四阶段
open my $in"|stap -p4 --skip-badvars --all-modules -x $pid -d '$exec_path' --ldd $d_so_args $stap_args -"
or die "Cannot run stap: $!\n";

修改好之后运行脚本,会生成一个内核模块

// -p 8682 是需要监控的进程的进程号
// -t 30 是指会采样30秒
./sample-bt-off-cpu -p 8692 -t 30

生成的内核模块名称形如 stap_xxxxx.ko模块名称 由于读者并不需要关心内核模块签名,故章节略过

运行内核模块统计数据

内核模块签名完成后,便可以使用 staprun 命令手工运行相关内核模块了 命令:

// 注意:签名脚本会将生产的内核模块重命名,需要将名字改回去……(脚本bug)
staprun -x {进程号} {内核模块名} > demo.bt

值得注意的是,监控的进程要有一定负载 systemtap 才可以采集到相关数据,即在采集时,同时需要要有一定请求量(通常是自己构造请求,压测进程)

将统计数据转换成火焰图

获得了统计数据 demo.bt 后,便可以使用火焰图工具绘制火焰图了 下载 FlameGraph,链接:

https://github.com/brendangregg/FlameGraph

命令:

./stackcollapse-stap.pl demo.bt > demo.folded
./flamegraph.pl demo.folded > demo.svg
alt
参考资料:https://zhuanlan.zhihu.com/p/147875569

eBPF

VTune Profiler

Toplev

https://github.com/andikleen/pmu-tools/wiki/toplev-manual

BCC tools

BPF Compiler Collection

https://github.com/iovisor/bcc

pcm Intel® Performance Counter Monitor

https://github.com/intel/pcm

pmu-tools

https://github.com/andikleen/pmu-tools

perf-tools

https://github.com/brendangregg/perf-tools

Latencytop

可以测试出内核态和用户态导致系统延迟的原因

https://www.latencytop.org/

PSI(Pressure Stall Information)

PSI 是 Linux 内核中的一项功能,旨在提供有关 CPU、内存和 I/O 子系统的性能压力情况的信息。它通过跟踪和报告不同子系统中的“压力事件”,帮助分析师和开发人员确定系统是否正在经历性能瓶颈。

https://facebookmicrosites.github.io/psi/docs/overview.html

trace-cmd

https://www.p99conf.io/session/analyze-virtual-machine-overhead-compared-to-bare-metal-with-tracing/

bpftrace

查询所有内核插桩和跟踪点

sudo bpftrace -l 'open'

systemtap

SystemTap 是一个在 Linux 系统上进行系统级跟踪和探测的工具。它提供了一种灵活的方式,通过编写脚本来捕获和分析系统的内核和用户空间活动。

orbit C/C++ Performance Profiler

https://github.com/google/orbit

proc 文件系统

trace 文件系统

BOLT

https://github.com/facebookincubator/BOLT

C++

Compiler Explorer

查询 C++ 代码编译成的 汇编代码

https://godbolt.org/

Quick C++ Benchmark

https://quick-bench.com/q/eP40RY6zDK-eJFdSSPBINa0apTM

Compare C++ Builds

可以测试、比较不同 C++ 代码的编译开销(CPU、内存、I/O)

https://build-bench.com/b/47ciR2_jQ0RuAt2fy1Pnk66b3yM

C++ Insights

https://cppinsights.io/

C++ Micro Benchmark

https://github.com/google/benchmark

数据库 benchmark 框架

BenchBase

BenchBase (formerly OLTPBench) is a Multi-DBMS SQL Benchmarking Framework via JDBC.

https://github.com/cmu-db/benchbase

sysbench

sysbench --db-driver=mysql --mysql-host=<hostname> --mysql-port=<port> --mysql-user=<username> --mysql-password=<password> --mysql-db=testdb --table-size=10000 --tables=1 --threads=1 --time=0 oltp_prepare

dbbench

https://github.com/memsql/dbbench

pointer-chasing

Utilities to measure read access times of caches, memory, and hardware prefetches for simple and fused operations

https://github.com/afborchert/pointer-chasing

性能压测工具

Stress

Stress-ng

SysBench

Apache Bench

mysqlslap

mysqlslap -u root --password=xxx -h 127.0.0.1 -P 888  0 -c 1 -i 1 --create-schema=test --query="sql-groupby-string-string_int_int";

Jmeter

Cutter 逆向工程

https://github.com/rizinorg/cutter
alt

本文由 mdnice 多平台发布

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值