笔记取自 <<BPF之巅-洞悉linux系统和应用>>
linux 下性能分析的目的是为了提升用户体验,降低运营成本。
性能测量的指标主要有如下几个方面:
延迟:多久完成一次请求或操作,以毫秒为单位
速率:每秒操作或请求的速率
吞吐量:通常指每秒传输的数据量,以byte为单位
利用率:某一个资源再一段时间内的繁忙程度
成本:开销
一、性能分析方法论
1)业务负载画像
有时候我们不需要对最终的性能结果进行分析,但是你需要指导到底对系统延迟造成多少影响
开展负载画像步骤如下:
1)业务负载是谁产生的(进程id 进程名、ip地址)
2)负载为什么会产生(代码路径、调用栈、火焰图)
3)负载的组成是什么(IOPS,吞吐量、负载类型)
4)负载随着时间怎么变化
书中使用的如下工具
1、vfsstat-bpfcc
vfsstat
工具检测对虚拟文件系统(VFS)接口的键调用,并显示每秒的摘要
TIME READ/s WRITE/s FSYNC/s OPEN/s CREATE/s
02:40:29: 126 75 0 5 0
02:40:30: 2158 7076 0 2420 0
02:40:31: 1560 140 0 1399 0
02:40:32: 6962 5854 0 2933 0
02:40:33: 5814 4584 0 5970 0
02:40:34: 3047 1650 0 2425 0
02:40:35: 3223 1380 0 478 0
02:40:36: 2169 756 0 445 0
02:40:37: 1004 899 0 273 0
02:40:38: 2487 1072 0 910 0
02:40:39: 1824 1305 0 305 0
02:40:40: 2081 80 0 1232 0
02:40:41: 359 287 0 58 0
02:40:42: 249 253 0 10 0
02:40:43: 157 185 0 0 0
02:40:44: 1387 853 0 319 0
02:40:45: 691 607 0 56 0
02:40:46: 2339 617 0 1079 0
02:40:47: 13842 161 0 2481 0
02:40:48: 18 17 0 2 0
02:40:49: 7 6 0 0 0
02:40:50: 167 185 0 23 0
上面的每一行代表什么呢?
我们看下bcc-tools 这个工具的源码
tools/vfsstat.py · haojane/bcc - Gitee.com--
b.attach_kprobe(event="vfs_read", fn_name="do_read")
b.attach_kprobe(event="vfs_write", fn_name="do_write")
b.attach_kprobe(event="vfs_fsync", fn_name="do_fsync")
b.attach_kprobe(event="vfs_open", fn_name="do_open")
b.attach_kprobe(event="vfs_create", fn_name="do_create")
kprobe 了 vfs的这几个系统调用,我们这里看下 do_fsync吧
这里有个问题标记下已经提了issue 再github上。
如果我们想看调用明细
sudo bpftrace -e 'kprobe:vfs_write{@[comm] = count()}'
显示列表
zhanglei@ubuntu:~$ sudo bpftrace -e 'kprobe:vfs_write{@[comm] = count()}'
Attaching 1 probe...
^C
@[sudo]: 1
@[InputThread]: 2
@[gnome-shell]: 9
@[gmain]: 71
@[gnome-terminal-]: 476
@[test]: 1458
我们发现test 程序调用了1458次。
2)下钻分析
下钻分析是从一个指标开始,然后把指标分成了多个部分
下钻分析步骤:
1、从业务最高层开始分析
2、检查下一层及细节
3、跳出最感兴趣的部分或者索引
4、如果问题没解决重复用个第二个步骤
3)USE方法论
针对一个资源要分别分析
使用率
饱和度
错误
4)linux 60秒分析
当排查一台机器性能很差时候,应该用下面的工具
1.uptime
这个工具可以快速检查平均负载,也就是有多少个任务需要被执行
zhanglei@ubuntu:~$ uptime
03:15:24 up 1:25, 1 user, load average: 0.01, 0.00, 0.00
这个可以了解1分钟、5分钟 15分钟滑动窗口的累计值
2.dmesg
zhanglei@ubuntu:~$ dmesg|tail
[ 16.603236] Bluetooth: BNEP socket layer initialized
[ 17.906691] e1000: ens33 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: None
[ 17.921045] IPv6: ADDRCONF(NETDEV_CHANGE): ens33: link becomes ready
[ 21.909484] loop8: detected capacity change from 0 to 8
[ 27.142783] rfkill: input handler disabled
[ 119.460749] rfkill: input handler enabled
[ 120.459583] Bluetooth: RFCOMM TTY layer initialized
[ 120.459594] Bluetooth: RFCOMM socket layer initialized
[ 120.459601] Bluetooth: RFCOMM ver 1.11
[ 129.438574] rfkill: input handler disabled
zhanglei@ubuntu:~$
3.vmstat
zhanglei@ubuntu:~$ vmstat 1
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 0 153440 164788 757736 0 0 52 99 74 145 1 1 98 0 0
0 0 0 153432 164788 757736 0 0 0 0 123 225 1 0 99 0 0
0 0 0 153432 164788 757736 0 0 0 0 419 748 3 1 97 0 0
0 0 0 153432 164788 757736 0 0 0 0 555 929 2 1 97 0 0
0 0 0 153432 164788 757736 0 0 0 0 1080 1852 4 4 92 0 0
0 0 0 153448 164788 757736 0 0 0 0 722 1301 4 3 93 0 0
0 0 0 153448 164788 757736 0 0 0 0 504 1029 2 1 98 0 0
r是cpu数量
free 空闲内存
si so 页的换入换出
us sy id wa 和st 这些是对所有cpu 取最后结果,分别代表用户态时间、系统态时间、等待io、以及被窃取时间(stolen time,虚拟化环境下被其他客户机所挤占的时间)
4.mpstat -P ALL 1
sudo apt install sysstat
zhanglei@ubuntu:~$ mpstat -P ALL 1
Linux 5.13.0-35-generic (ubuntu) 03/19/2022 _x86_64_ (2 CPU)
03:47:12 AM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
03:47:13 AM all 0.00 0.00 1.02 0.00 0.00 0.00 0.00 0.00 0.00 98.98
03:47:13 AM 0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
03:47:13 AM 1 0.00 0.00 2.02 0.00 0.00 0.00 0.00 0.00 0.00 97.98
03:47:13 AM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
03:47:14 AM all 2.19 0.00 2.19 0.00 0.00 0.00 0.00 0.00 0.00 95.63
03:47:14 AM 0 1.05 0.00 1.05 0.00 0.00 0.00 0.00 0.00 0.00 97.89
03:47:14 AM 1 3.41 0.00 3.41 0.00 0.00 0.00 0.00 0.00 0.00 93.18
03:47:14 AM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
03:47:15 AM all 2.20 0.00 1.65 0.00 0.00 0.00 0.00 0.00 0.00 96.15
03:47:15 AM 0 1.09 0.00 1.09 0.00 0.00 0.00 0.00 0.00 0.00 97.83
03:47:15 AM 1 3.33 0.00 2.22 0.00 0.00 0.00 0.00 0.00 0.00 94.44
^C
Average: CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
Average: all 1.42 0.00 1.60 0.00 0.00 0.00 0.00 0.00 0.00 96.98
Average: 0 0.70 0.00 0.70 0.00 0.00 0.00 0.00 0.00 0.00 98.60
Average: 1 2.17 0.00 2.53 0.00 0.00 0.00 0.00 0.00 0.00 95.31
打印每个cpu 使用情况
5.pidstat 1
zhanglei@ubuntu:~$ pidstat 1
Linux 5.13.0-35-generic (ubuntu) 03/19/2022 _x86_64_ (2 CPU)
03:48:02 AM UID PID %usr %system %guest %wait %CPU CPU Command
03:48:03 AM 1000 3793 0.93 1.85 0.00 0.00 2.78 1 pidstat
03:48:03 AM UID PID %usr %system %guest %wait %CPU CPU Command
03:48:04 AM 0 737 1.00 0.00 0.00 0.00 1.00 0 vmtoolsd
03:48:04 AM 1000 1492 1.00 2.00 0.00 0.00 3.00 0 Xorg
03:48:04 AM 1000 1666 1.00 1.00 0.00 0.00 2.00 0 gnome-shell
03:48:04 AM 1000 1838 0.00 1.00 0.00 0.00 1.00 0 vmtoolsd
03:48:04 AM 1000 1980 2.00 0.00 0.00 0.00 2.00 0 gnome-terminal-
03:48:04 AM 1000 3793 0.00 1.00 0.00 0.00 1.00 1 pidstat
^C
Average: UID PID %usr %system %guest %wait %CPU CPU Command
Average: 0 737 0.48 0.00 0.00 0.00 0.48 - vmtoolsd
Average: 1000 1492 0.48 0.96 0.00 0.48 1.44 - Xorg
Average: 1000 1666 0.48 0.48 0.00 0.48 0.96 - gnome-shell
Average: 1000 1838 0.00 0.48 0.00 0.00 0.48 - vmtoolsd
Average: 1000 1980 0.96 0.00 0.00 0.00 0.96 - gnome-terminal-
Average: 1000 3793 0.48 1.44 0.00 0.00 1.92 - pidstat
展示每个进程的cpu使用情况
6.iostat
这个io指标展示了设备存储的io指标
Device r/s rkB/s rrqm/s %rrqm r_await rareq-sz w/s wkB/s wrqm/s %wrqm w_await wareq-sz d/s dkB/s drqm/s %drqm d_await dareq-sz aqu-sz %util
loop0 0.00 0.00 0.00 0.00 0.21 1.21 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
loop1 0.01 0.05 0.00 0.00 1.36 7.80 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
loop2 0.01 0.05 0.00 0.00 0.42 8.07 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
loop3 0.01 0.15 0.00 0.00 1.35 17.35 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
loop4 0.01 0.15 0.00 0.00 0.82 19.18 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
loop5 0.01 0.05 0.00 0.00 1.66 7.28 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
loop6 0.07 2.42 0.00 0.00 1.31 33.70 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.03
loop7 0.01 0.05 0.00 0.00 1.56 7.48 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
loop8 0.00 0.00 0.00 0.00 0.17 1.50 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
sda 2.54 104.54 0.95 27.24 0.96 41.11 32.12 189.75 12.35 27.78 0.40 5.91 0.00 0.00 0.00 0.00 0.00 0.00 0.02 1.88
scd0 0.00 0.00 0.00 0.00 0.27 0.23 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
avg-cpu: %user %nice %system %iowait %steal %idle
0.52 0.00 0.52 0.00 0.00 98.96
Device r/s rkB/s rrqm/s %rrqm r_await rareq-sz w/s wkB/s wrqm/s %wrqm w_await wareq-sz d/s dkB/s drqm/s %drqm d_await dareq-sz aqu-sz %util
avgqu-sz 设备请求队列的平均长度,多块设备的虚拟磁盘来说是并行请求
%util 设备使用率。这是设备繁忙程度的百分比,大于百分之60性能通常会变差
7.free -m
空闲内存
8.sar -n DEV 1
它可以对不同的指标进行组合,这个命令可以通过接口吞吐信息rxkb/s和txkb每秒来检查指标是否有指标到了上限
9.sar -n TCP、ETCP 1
zhanglei@ubuntu:~$ sar -n TCP,ETCP 1
Linux 5.13.0-35-generic (ubuntu) 03/19/2022 _x86_64_ (2 CPU)
04:15:31 AM active/s passive/s iseg/s oseg/s
04:15:32 AM 0.00 0.00 0.00 0.00
04:15:31 AM atmptf/s estres/s retrans/s isegerr/s orsts/s
04:15:32 AM 0.00 0.00 0.00 0.00 0.00
04:15:32 AM active/s passive/s iseg/s oseg/s
04:15:33 AM 0.00 0.00 0.00 0.00
04:15:32 AM atmptf/s estres/s retrans/s isegerr/s orsts/s
04:15:33 AM 0.00 0.00 0.00 0.00 0.00
^C
Average: active/s passive/s iseg/s oseg/s
Average: 0.00 0.00 0.00 0.00
Average: atmptf/s estres/s retrans/s isegerr/s orsts/s
Average: 0.00 0.00 0.00 0.00 0.00
zhanglei@ubuntu:~$
active/s 本地发起的tcp链接数
passive/s 远端发起的连接数
retrans 每秒tcp 重试数目
10.top 就不写了
二、bcc 工具清单
清单:
execsnoop
opensnoop
ext4slower
biolatency
biosnoop
cachestat
tcpconnect
tcpaccept
tcpretrans
runqlat
profile
1.execsnoop
为每个创建的进程创建信息
3 warnings generated.
PCOMM PID PPID RET ARGS
vim 4073 1988 0 /usr/bin/vim a.c
tracker-store 4075 1440 0 /usr/libexec/tracker-store
systemctl 4081 2009 0 /bin/systemctl is-enabled -q whoopsie
apport-checkrep 4082 2009 0 /usr/share/apport/apport-checkreports
tracker-extract 4087 1440 0 /usr/libexec/tracker-extract
apport-checkrep 4102 2009 0 /usr/share/apport/apport-checkreports --system
2.opensnoop
为每次调用open打印一行信息
PID COMM FD ERR PATH
773 irqbalance 6 0 /proc/interrupts
773 irqbalance 6 0 /proc/stat
737 vmtoolsd 9 0 /proc/meminfo
737 vmtoolsd 9 0 /proc/vmstat
737 vmtoolsd 9 0 /proc/stat
737 vmtoolsd 9 0 /proc/zoneinfo
737 vmtoolsd 9 0 /proc/uptime
737 vmtoolsd 9 0 /proc/diskstats
3.ext4slower
跟踪ext4文件系统把耗时超过某个阈值的操作打印出来
Tracing ext4 operations slower than 10 ms
TIME COMM PID T BYTES OFF_KB LAT(ms) FILENAME
4.biolatency
打印缓存命中率。可以检查缓存使用较高或者较低的问题
HITS MISSES DIRTIES HITRATIO BUFFERS_MB CACHED_MB
0 0 0 0.00% 155 582
1 0 0 100.00% 155 582
0 0 0 0.00% 155 582
0 0 0 0.00% 155 582
0 0 4 0.00% 155 582
5.tcpconnect
6.tcpaccept
7.tcpretrans
每次tcp重传会打印一条数据,如果发生再elasticsearch 可能是网络问题,如果是SYN_SENT可能是cpu饱和
8.runqlt
<pre>Tracing run queue latency... Hit Ctrl-C to end.
c^C
usecs : count distribution
0 -> 1 : 14 |* |
2 -> 3 : 59 |******* |
4 -> 7 : 91 |*********** |
8 -> 15 : 69 |******** |
16 -> 31 : 76 |********* |
32 -> 63 : 220 |**************************** |
64 -> 127 : 309 |****************************************|
128 -> 255 : 100 |************ |
256 -> 511 : 55 |******* |
512 -> 1023 : 18 |** |
1024 -> 2047 : 11 |* |
2048 -> 4095 : 3 | |
</pre>
可以定位超出预期cpu等待时间
9.profile
可以定位哪些代码路径消耗了cpu,周期采样
b'mpt_put_msg_frame'
b'mpt_put_msg_frame'
b'mptscsih_qcmd'
b'mptspi_qcmd'
b'scsi_queue_rq'
b'blk_mq_dispatch_rq_list'
b'__blk_mq_do_dispatch_sched'
b'__blk_mq_sched_dispatch_requests'
b'blk_mq_sched_dispatch_requests'
b'__blk_mq_run_hw_queue'
b'__blk_mq_delay_run_hw_queue'
b'blk_mq_run_hw_queue'
b'blk_mq_sched_insert_requests'
b'blk_mq_flush_plug_list'
b'blk_flush_plug_list'
b'blk_finish_plug'
b'ext4_writepages'
b'do_writepages'
b'__filemap_fdatawrite_range'
b'file_write_and_wait_range'
b'ext4_sync_file'
b'vfs_fsync_range'
b'ext4_buffered_write_iter'
b'ext4_file_write_iter'
b'new_sync_write'
b'vfs_write'
b'ksys_write'
b'__x64_sys_write'
b'do_syscall_64'
b'entry_SYSCALL_64_after_hwframe'
__write
main
__libc_start_main
- test (4324)