Akemi

系统性能追踪工具systemtap/eBPF

2025/04/29

systemtap

SystemTap 是一种动态追踪和分析工具,允许用户通过编写脚本实时监控内核及用户空间程序的运行状态,常用于性能调优、故障排查和内核行为分析

核心组件

  • SystemTap 工具链:包含 stap(脚本编译器)、staprun(内核模块加载器)等工具。
  • 内核支持:依赖 kernel-devel、kernel-debuginfo 包(提供内核符号和调试信息)。
  • 脚本库(Tapsets):预定义的探针和函数库,简化脚本编写(如 syscall.* 表示系统调用探针)。

工作流程

  1. 编写脚本:用户编写 .stp 脚本,定义探针和触发动作(如记录数据、统计计数)。
  2. 编译脚本stap 将脚本转换为 C 代码,并编译为内核模块(.ko 文件)。
  3. 加载模块staprun 将模块插入内核,开始监控。
  4. 收集数据:探针触发时执行脚本逻辑,结果输出到终端或文件。
  5. 卸载模块:监控结束后,自动或手动移除内核模块。

安装与使用systemtap

正常情况下,SystemTap脚本只能在安装了SystemTap的系统上运行。这可能意味着在要分析的每个系统上安装完整的SystemTap编译器、内核头文件、源代码和debuginfo内核包
也就是,需要一个专门的systemtap机器

1
2
3
4
5
6
7
8
9
10
11
12
13
# 安装
yum -y install systemtap

# 自动安装依赖
会自动安装kernel-debuginfo
stap-prep

# 手动启用仓库
yum-config-manager --enable debuginfo
yum clean all
yum makecache
# 重新尝试安装
yum install -y kernel-devel-$(uname -r) kernel-debuginfo-$(uname -r)

stap命令是systemtap的前端

当脚本第一次编译时,systemtap会 在用户的家目录里面的.Systemtap目录中缓存一个已编译对象。如果检测到源脚本未被修改,则stap将在后续运行中使用缓存的对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
脚本执行的五个阶段pass:
1.parse 检查语法错误
2.elaborate 函数展开
3.translate 将脚本转换成C文件
4.build 将C源文件编译成内核模块
5.run 将编译好的内核模块插入内核

stap -v /usr/share/systemtap/examples/process/syscalls_by_proc.stp
Pass 1: parsed user script and 473 library scripts using 272056virt/69204res/3508shr/65836data kb, in 250usr/30sys/276real ms.
Pass 2: analyzed script: 4 probes, 2 functions, 101 embeds, 5 globals using 290032virt/87984res/6496shr/81712data kb, in 14520usr/4510sys/6555real ms.
Missing separate debuginfos, use: debuginfo-install kernel-3.10.0-1160.119.1.el7.x86_64
Pass 3: translated to C into "/tmp/stap98YNhM/stap_e2f1b5cd07262cd74d245a3f7b5661e9_132280_src.c" using 290032virt/88188res/6700shr/81712data kb, in 10usr/0sys/20real ms.
Pass 4: compiled C into "stap_e2f1b5cd07262cd74d245a3f7b5661e9_132280.ko" in 7260usr/1380sys/8331real ms.
Pass 5: starting run.
Collecting data... Type Ctrl-C to exit and display results

eBPF

允许用户在不修改内核源码或加载内核模块的情况下,安全、高效地运行自定义程序,用于实时监控、网络处理、安全控制等场景

用户空间启用的,受限于它所使用的内存数量,并且对设备的访问受限

工作原理是将程序附加到各种内核点,如kprobes、跟踪点和perf事件。有许多性能分析工具利用了扩展的内核功能,不仅允许过滤数据包。这些增强允许在Linux上执行定制的分析程序,用于动态跟踪、静态跟踪和分析事件

已成为Linux内核观测和网络优化的标准方案

特性 eBPF SystemTap
安全性 通过验证器确保安全,默认允许生产环境使用。 依赖手动审查,可能引发内核崩溃。
性能开销 极低(JIT编译 + 高效事件绑定)。 较高(依赖临时模块和脚本解释)。
内核版本要求 需要较新内核(4.x 以上)。 支持旧内核,但功能受限。
编程复杂度 需掌握C语言和BPF API,工具链完善。 脚本化开发,但调试复杂。
社区趋势 已成为Linux内核观测和网络优化的标准方案。 逐渐被eBPF替代(如RHEL 9默认支持eBPF)。

BCC工具集

编写eBPF程序需要从内核源代码编译并链接到eBPF库。这对于内核开发人员来说很好,但是对于其他人来说,比如那些在生产系统上工作的人,拥有现有的程序可能是更理想的方法。BCC包含编写程序所需的组件,还提供了示例程序和用于调试和诊断性能问题的现有工具。

BCC是一套基于 eBPF 技术的开源工具集,旨在简化 eBPF 程序的开发、调试和部署。它通过提供高层语言接口(如 Python、Lua)和预封装的内核观测工具,让开发者无需深入掌握底层内核细节即可快速实现性能分析、网络监控、安全控制等功能。

1
2
3
4
5
6
7
8
yum -y install bcc-tools

默认路径/usr/share/bcc/tools/
也可以加到PATH中

工具文档:
/usr/share/bcc/tools
/usr/share/bcc/tools/doc

execsnoop追踪execve()系统调用

execsnoop追踪execve()系统调用并且展示参数和返回值的细节

1
2
3
4
5
6
7
8
9
10
11
12
13
cd /usr/share/bcc/tools/
./execsnoop
PCOMM PID PPID RET ARGS
sshd 117876 57783 0 /usr/sbin/sshd -D -oCiphers=aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr,aes256-cbc,aes128-gcm@openssh.com,aes128-ctr,aes128-cb -oMACs=hmac-sha2-256-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha2- -oGSSAPIKexAlgorithms=gss-curve25519-sha256-,gss-nistp256-sha256-,gss-group14-sha256-,gss-group16-sha512-,gss-gex-sha1-,gss-grou -oKexAlgorithms=curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-h -oHostKeyAlgorithms=ecdsa-sha2-nistp256,ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384,ecdsa-sha2-nistp384-cert-v0 -oPubkeyAcceptedKeyTypes=ecdsa-sha2-nistp256,ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384,ecdsa-sha2-nistp384-ce -oCASignatureAlgorithms=ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-ed25519,rsa-sha2-256,rsa-sha2-512,ssh-rs -R
unix_chkpwd 117878 117876 0 /usr/sbin/unix_chkpwd root nonull
unix_chkpwd 117879 117876 0 /usr/sbin/unix_chkpwd root chkexpiry
sshd 117881 57783 0 /usr/sbin/sshd -D -oCiphers=aes256-gcm@openssh.com,chacha20-pol

PCOMM: 父进程的命令名称
PID: 进程ID
PPID: 父进程ID
RET: 返回值
ARGS: 带参数的文件名

opensnoop追踪open()系统调用

opensnoop工具追踪open()系统调用,列出进程的名字和路径名字细节。opensnoop是一个在应用启动期间非常有用的发现配置文件和日志文件的工具

1
2
3
4
5
6
7
8
9
10
11
12
13
cd /usr/share/bcc/tools/
./opensnoop
PID COMM FD ERR PATH
772 irqbalance 6 0 /proc/interrupts
772 irqbalance 6 0 /proc/stat
772 irqbalance 6 0 /proc/irq/29/smp_affinity
772 irqbalance 6 0 /proc/irq/27/smp_affinity
772 irqbalance 6 0 /proc/interrupts
772 irqbalance 6 0 /proc/stat
772 irqbalance 6 0 /proc/irq/29/smp_affinity
772 irqbalance 6 0 /proc/irq/27/smp_affinity

敲回车,irqbalance为了监控中断状态,它会周期性地读取/proc中的文件

xfsslower追踪XFS操作

xfsslower显示xfs文件系统的读,写,打开,文件同步,默认查看慢于10ms的进程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
./xfsslower
Tracing XFS operations slower than 10 ms
TIME COMM PID T BYTES OFF_KB LAT(ms) FILENAME
02:08:32 b'yum' 117971 S 0 0 14.36 b'Group'
02:25:55 b'yum' 118664 S 0 0 14.84 b'containernetworking-plugins-1.4.'
02:26:51 b'ldconfig' 119683 S 0 0 34.16 b'ld.so.cache~'
02:26:51 b'yum' 118664 S 0 0 11.01 b'packages.db-journal'

TIME - 时间戳
COMM - 执行文件操作的进程名
PID - 进程的PID
T - 操作类型(R=读,W=写,S=同步等)
BYTES - 操作涉及的数据量大小(单位:字节)
OFF_KB - 文件内的偏移量(单位:千字节,KB)
LAT(ms) - 操作耗时
FILENAME - 被操作的文件路径或名称

biolatency追踪块设备延迟

biolatency工具跟踪块设备I/O(磁盘I/O),记录I/O时延(时间)的分布。按下Ctrl+C键结束跟
踪,生成直方图并显示在终端上

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
./biolatency
Tracing block device I/O... Hit Ctrl-C to end.
usecs : count distribution
0 -> 1 : 0 | |
2 -> 3 : 0 | |
4 -> 7 : 0 | |
8 -> 15 : 0 | |
16 -> 31 : 0 | |
32 -> 63 : 1 |* |
64 -> 127 : 0 | |
128 -> 255 : 11 |****************** |
256 -> 511 : 24 |****************************************|
512 -> 1023 : 19 |******************************* |
1024 -> 2047 : 1 |* |
2048 -> 4095 : 1 |* |
4096 -> 8191 : 17 |**************************** |

usecs(延迟区间)延迟时间范围,单位是微秒(μs)。
count(计数)该延迟区间内发生的 I/O 操作次数。
distribution(分布直方图)用星号(*)直观展示各区间操作次数的比例,越长表示次数越多。

biosnoop查看块设备IO情况

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
./biosnoop
TIME(s) COMM PID DISK T SECTOR BYTES LAT(ms)
0.000000 kworker/0:2 122248 <unknown> R 18446744073709551615 8 0.28
2.048004 kworker/0:2 122248 <unknown> R 18446744073709551615 8 0.33
4.095876 kworker/0:2 122248 <unknown> R 18446744073709551615 8 0.21
4.354287 kworker/u8:3 38 sda W 58324592 4096 2.59
6.143810 kworker/0:2 122248 <unknown> R 18446744073709551615 8 0.20
8.192088 kworker/0:2 122248 <unknown> R 18446744073709551615 8 0.37
10.240044 kworker/0:2 122248 <unknown> R 18446744073709551615 8 0.36
12.287971 kworker/0:2 122248 <unknown> R 18446744073709551615 8 0.33
14.335888 kworker/0:2 122248 <unknown> R 18446744073709551615 8 0.23
16.383926 kworker/0:2 122248 <unknown> R 18446744073709551615 8 0.29

TIME(s):工具启动后0秒时触发的操作。
COMM:内核工作线程 kworker/0:2。
PID:进程 ID 为 122248。
DISK:目标磁盘未知(可能是虚拟设备或元数据操作)。
T:读操作R,写操作W。
SECTOR:扇区号
BYTES:传输了 8 字节。
LAT(ms):操作耗时,单位毫秒。

cachestat跟踪内核页缓存函数—热点分析

cachestat工具跟踪内核页缓存函数,并以每秒的速度打印摘要。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
./cachestat
HITS MISSES DIRTIES HITRATIO BUFFERS_MB CACHED_MB
0 137824 0 0.00% 1620 1379
830 101376 0 0.81% 1725 1283
99 102400 0 0.10% 1817 1196
0 103034 0 0.00% 1886 1115
256 101376 0 0.25% 1957 1046
0 99529 0 0.00% 2010 992
671 98304 0 0.68% 2041 960

测试命令:
dd if=/dev/sda2 of=/dev/null

HITS:缓存命中次数;
MISSES:缓存未命中次数;
DIRTIES:加入缓存脏页数;
RATIO:缓存命中率;
BUFFERS_MB:buffers大小,单位:MB;
CACHED_MB:cache大小,单位:MB;

gethostlatency追踪解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
./gethostlatency
TIME PID COMM LATms HOST
04:56:00 122371 ping 9.82 baidu.com
04:56:05 122372 ping 1.71 google
04:56:07 122373 ping 8.55 google.com
04:57:07 122374 isc-worker0000 0.02 127.0.0.1
04:57:07 122374 isc-worker0000 0.01 ::1
04:57:18 122379 isc-worker0000 0.01 127.0.0.1
04:57:18 122379 isc-worker0000 0.01 ::1

TIME 操作触发的时间(时:分:秒)
PID 发起主机名解析的进程 ID
COMM 进程名称(例如 ping、isc-worker0000)
LATms 主机名解析的延迟,单位:ms
HOST 进程尝试解析的目标主机名或 IP 地址
CATALOG
  1. 1. systemtap
    1. 1.0.1. 核心组件
    2. 1.0.2. 工作流程
    3. 1.0.3. 安装与使用systemtap
  • 2. eBPF
    1. 2.1. BCC工具集
      1. 2.1.1. execsnoop追踪execve()系统调用
      2. 2.1.2. opensnoop追踪open()系统调用
      3. 2.1.3. xfsslower追踪XFS操作
      4. 2.1.4. biolatency追踪块设备延迟
      5. 2.1.5. biosnoop查看块设备IO情况
      6. 2.1.6. cachestat跟踪内核页缓存函数—热点分析
      7. 2.1.7. gethostlatency追踪解析