提到如何动静追踪过程中的零碎调用,置信大家第一工夫都能想到 strace,它的根本用法非常简单,非常适合用来解决“为什么这个软件无奈在这台机器上运行?”这类问题。但如果须要分析线上服务(特地是提早敏感型)的某些零碎调用的提早时,strace 则不那么适合,因为它引入的开销会十分大,从性能剖析巨匠 Brendan Gregg 的测试后果得悉,被 strace 追踪的指标过程的运行速度会升高 100 倍以上,这对生产环境来说将是个劫难。
那么是否有比拟好用的工具用在生产环境上呢?答案是必定的,上面将介绍两款工具的常用命令,不便大家须要时查阅。
Perf
家喻户晓,perf 是 Linux 零碎下十分弱小的性能工具,由 Linux 内核开发人员在一直演进和优化。除了能够剖析 PMU (Performance Monitoring Unit) 硬件事件,内核事件等通用性能外,perf 还提供了其余“子模块”,比方 sched 剖析调度器,timechart 依据负载特色可视化零碎行为,c2c 剖析可能存在的 false sharing(RedHat 在大量 Linux 的利用上,测试过这套 c2c 的开发原型,胜利地发现了很多热点的伪共享缓存行问题。)等, 而 trace 则可用于剖析零碎调用,其性能十分弱小,并保障了能够承受的开销—— 运行速度仅加快 1.36 倍 (dd 作为测试负载)。咱们一起看下几个罕用的场景:
-
调用 syscall 数量的 top 排行榜
perf top -F 49 -e raw_syscalls:sys_enter --sort comm,dso --show-nr-samples
从输入能够看到在采样期间,kube-apiserver 的调用 syscall 的次数最多。
-
显示超过肯定提早的零碎调用信息
perf trace --duration 200
从输入中能够看到过程名称、pid,超过 200 ms 的具体零碎调用参数和返回值。
-
统计某个过程一段时间内零碎调用的开销
perf trace -p $PID -s
从输入中能够看到各零碎调用的次数,返回谬误次数,总提早,均匀提早等信息。
-
咱们也能够进一步剖析高提早的调用栈信息
perf trace record --call-graph dwarf -p $PID -- sleep 10
-
对一组工作进行 trace,比方后盾有 2 个 bpf 工具在运行,咱们想看下它们零碎调用应用状况,就能够先将它们增加到 perf_event 这个 cgroup 下,再执行 perf trace:
mkdir /sys/fs/cgroup/perf_event/bpftools/ echo 22542 >> /sys/fs/cgroup/perf_event/bpftools/tasks echo 20514 >> /sys/fs/cgroup/perf_event/bpftools/tasks perf trace -G bpftools -a -- sleep 10
perf-trace 的应用就介绍到这里,更多的用法请参考 man 手册,从下面能够看到 perf-trace 的性能十分弱小,依据 pid 或 tid 就能够进行过滤。但仿佛没有对容器和 K8S 环境进行便捷的反对。不必焦急,接下来介绍的这个工具就是针对容器和 K8S 环境的。
Traceloop
对于 Traceloop 大家可能有点生疏,但提到 BCC 想必大家就感觉相熟了。BCC 的前端是 Python/C++,其所属 iovisor 下还有一个我的项目叫 gobpf 是 BCC 的 go binding。而 Traceloop 则是基于 gobpf 库进行开发的,此我的项目的次要指标利用场景是容器、K8S 环境。其原理比较简单,其架构如图所示:
外围步骤如下:
- 利用 bpf helper 获取 cgroup id,依据 cgroup id 而不是 pid、tid 进行过滤。
- 每个 cgroup id 对应一个 bpf tail call,通过这种形式实现对此 cgroup id 对应的 perf ring buffer 进行写入。
- 用户空间依据 cgroup id 读取对应的 perf ring buffer。
须要留神的是,以后 cgroup id 的获取形式是通过 bpf helper:bpf_get_current_cgroup_id 来获取的,这个 id 是 cgroup v2 才有的。因而只实用于开启了 cgroup v2 的环境。尚不确定此我的项目团队是否有动向通过读取 nsproxy 数据结构等形式来对 cgroup v1 进行反对,因而在这里只做简略介绍。随着 K8S 1.19 版本开始反对 cgroup v2,期待 cgroup v2 能尽快遍及起来。以下应用 Centos 8 4.18 版本内核进行简略的演示:在 traceloop 退出时 dump 零碎调用信息
sudo -E ./traceloop cgroups --dump-on-exit /sys/fs/cgroup/system.slice/sshd.service
从输入中能够看到,其输入和 strace/perf trace 相似,只是针对 cgroup 进行过滤。须要留神的是 Centos 8 没有像 Ubuntu 将 cgroup v2 挂载到 /sys/fs/cgroup/unified,而是间接挂载到 /sys/fs/cgroup 下,在应用前倡议执行 mount -t cgroup2
来确定挂载信息。
对于 K8S 平台,该团队将 traceloop 集成到 Inspektor Gadget 我的项目中,通过 kubectl 插件来运行,因为管网给出具体的 gif 示例,在这里就不做过多介绍了,对 cgroup v2 有需要的敌人能够试一试。
Benchmark
从 benchmark 后果看,strace 的引起的目标程序性能降落最大,perf trace 次之,traceloop 最小。
总结
strace 仍然是解决“为什么这个软件无奈在这台机器上运行?”相干问题的利器,但对于剖析零碎调用提早等问题,perf trace 是适合的抉择,其也是基于 BPF 的实现,对于应用 cgroup v2 的容器、K8S 环境,traceloop 会更不便一些。