7.1-性能与测试工具
一、性能分析
网络部分
流程:
在虚拟机上开两台机器,利用iperf工具测试两台机器间网络吞吐量,一种是NAT模式下,通过虚拟网卡本机通信的情况,一种是bridge模式,通过局域网关转发后回到另外一台主机,需要经过网络的情况。
tcp:
iperf3 -c 192.168.1.7 --> 17Mb bridge网口
iperf3 -c 192.168.199.129 --> 15Mb nat网口udp:
iperf3 -u -b 200M -c 192.168.1.7 --> 75Mb bridge网口
iperf3 -u -b 200M -c 192.168.199.129 --> 100Mb nat网口
这只是一个简单的举例,并不能说明任何结论,但可以学会iperf3的使用命令,也可以学会分析其中原因,比如tcp传输下,实际上应该是nat更快于bridge,但是却更慢,可能是由于TCP协议的拥塞控制机制和确认重传机制在短路径、低延迟的NAT模式下触发了更激进的行为,导致瞬时速率波动。
磁盘和文件部分
流程:
在虚拟机上新分配一块磁盘,利用fio工具,测试iops(每秒钟磁盘操作次数),通过不同的命令,可以测试出磁盘和文件性能的不同,因为磁盘是更底层的,只有read和write两种操作,而文件会提供更多的参数,比如io的方式(同步、异步),io线程的数量等。
磁盘:
./fio/fio -filename=/dev/nvme0n3 -name=nvmetest -->IOPS=118k文件系统(xfs)
./fio/fio -filename=/mnt/io.data -size=1G -name=nvmetest -->iops = 77.6k-filename:指定测试文件的位置和名称
-size:设置测试文件的大小为 1 GB fio 会在这个文件上执行 I/O 操作
-name:为本次测试任务指定一个名称(nvmetest),用于在输出日志中标识
数据库部分
流程:
数据库是在文件上层的存储,在数据库中创建一个表,利用mysqlslap工具,编写增删查改四种语句,可以测试执行如1万条sql所需要的时间。
增:
mysqlslap -q "insert into PA.teacher(t_name)values('k')" -c 4 --number-of-queries=10000 -uroot -p6.258 seconds查:
mysqlslap -q "select * from PA.teacher order by t_id desc limit 1;" -c 4 --number-of-queries=10000 -uroot -p0.740 seconds改:
mysqlslap -q "update PA.teacher set t_name='q' where t_id=1001;" -c 4 --number-of-queries=10000 -uroot -p1.078 seconds删:
mysqlslap -q "delete from PA.teacher order by t_id asc limit 1;" -c 4 --number-of-queries=10000 -uroot -p16.007 seconds删:不每一次都重构后排序
mysqlslap -q "delete from PA,teacher where t id=188;" -c 4 --number-of-queries=10000 -uroot -p0.740 seconds
HTTP服务器部分
流程:
在一台虚拟机上启动如Nginx服务后,用wrk工具,访问对应的ip和端口,测试服务器的qps(每秒钟处理请求的数量)
./wrk -t 50 -c 100 -d30s http://192.168.199.129:8000/-t 50 使用 50 个线程 进行测试
-c 100 模拟 100 个并发连接(即同时有 100 个 HTTP 请求)
-d30s 测试持续 30 秒结果:
296371 requests in 30.01s, 42.15MB read
Requests/sec: 9876.23 (QPS,每秒请求数)
Transfer/sec: 1.40MB (每秒传输数据量)
二、火焰图
常用的性能调优工具 perf 等,在呈现内容上只能单一的列出调用栈或者非层次化的时间分布,不够直观。配合使用火焰图,它将 perf 等工具采集的数据呈现得更为直观。
初识火焰图
火焰图有以下特征:
- 每一列代表一个调用栈,每一个格子代表一个函数
- 纵轴展示了栈的深度,按照调用关系从下到上排列。最顶上格子代表采样时,正在占用 cpu 的函数。
- 横轴的意义是指:火焰图将采集的多个调用栈信息,通过按字母横向排序的方式将众多信息聚合在一起。需要注意的是它们的先后顺序与时间无关。
- 横轴格子的宽度代表其在采样中出现频率,所以一个格子的宽度越大,说明它是瓶颈原因的可能性就越大。
- 火焰图格子的颜色是随机的暖色调,方便区分各个调用信息。
- 其他的采样方式也可以使用火焰图, on-cpu 火焰图横轴是指 cpu 占用时间,off-cpu 火焰图横轴则代表阻塞时间。
- 采样可以是单线程、多线程、多进程甚至是多 host,进阶用法可以参考附录进阶阅读
| 火焰图类型 | 横轴含义 | 纵轴含义 | 使用情况 | 采样方式 |
|---|---|---|---|---|
| on-CPU火焰图 | CPU占用时间 | 调用栈 | 当cpu占有率高的时候,需要分析函数的cpu占有率情况 | 固定频率采样 CPU调用栈 |
| Off-CPU火焰图 | 阻塞时间 | 调用栈 | 当cpu占有率低的时候(I/O、网络等阻塞、锁竞争、死锁导致的性能下降),需要分析函数的cpu占有率情况 | 固定频率采样 阻塞事件调用栈 |
| 内存火焰图 | 内存申请/释放函数调用次数 | 调用栈 | 内存泄露问题;内存占用高的对象/申请内存多的函数;虚拟内存或物理内存泄露问题 | 跟踪malloc/free;跟踪brk;跟踪mmap;跟踪页错误 |
| Hot/Cold火焰图 | 将On-CPU和Off-CPU火焰图结合,综合展示 | 调用栈 | 需要结合CPU占用以及阻塞分析的场景;Off-CPU火焰图无法直观判断问题的场景 | On-CPU火焰图和Off-CPU火焰图结合 |
绘制火焰图
先安装火焰图FlameGraph脚本,这是一个第三方的绘制工具
git clone https://gitee.com/mirrors/FlameGraph.git
第一步:采集堆栈(root权限)
使用perf工具抓取程序的运行堆栈,假设 ./test的运行pid是5000,通过perf命令检测采样,会在执行的目录参数perf.data
perf record -F 99 -p 5000 -g -- sleep 30perf record 表示采集系统事件,没有使用 -e 指定采集事件,则默认采集 cycles(即 CPU clock周期)
-F 99 表示每秒 99 次
-p 5000是进程号,即对哪个进程进行分析
-g 表示记录调用栈
sleep 30 则是持续 30 秒.
第二步:折叠堆栈
使用perf script 工具对perf.data进行解析,记录调用栈的情况(还未折叠)
perf script -i perf.data &> perf.unfold
再使用stackcollapse-perf.pl将 perf 解析出的内容 perf.unfold 中的符号进行折叠
./FlameGraph/stackcollapse-perf.pl perf.unfold &> perf.folded
第三步:生成火焰图
生成svg图(火焰图)
./FlameGraph/flamegraph.pl perf.folded > test_oncpu.svg
也可以使用管道,把第二第三步整合为一条指令:
perf script | ./FlameGraph/stackcollapse-perf.pl | ./FlameGraph/flamegraph.pl > test_oncpu.svg
火焰图的局限性
1.对于O3优化后的一些函数,是没有堆栈的,分析不了他的cpu占用情况
2.对于内联函数,也无法分析
3.对于c++的lambda表达式,也无法分析
