搜索中...
🔍

未找到相关结果

Akemi

系统性能追踪工具systemtap/eBPF

字数统计: 2.5k阅读时长: 11 min
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.1. 核心组件
    2. 1.2. 工作流程
    3. 1.3. 安装与使用systemtap
  2. 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追踪解析