关于tidb:线上环境-Linux-系统调用追踪

40次阅读

共计 2412 个字符,预计需要花费 7 分钟才能阅读完成。

提到如何动静追踪过程中的零碎调用,置信大家第一工夫都能想到 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 作为测试负载)。咱们一起看下几个罕用的场景:

  1. 调用 syscall 数量的 top 排行榜

    perf top -F 49 -e raw_syscalls:sys_enter --sort comm,dso --show-nr-samples

    从输入能够看到在采样期间,kube-apiserver 的调用 syscall 的次数最多。

  2. 显示超过肯定提早的零碎调用信息

    perf trace --duration 200

    从输入中能够看到过程名称、pid,超过 200 ms 的具体零碎调用参数和返回值。

  3. 统计某个过程一段时间内零碎调用的开销

    perf trace -p $PID  -s

    从输入中能够看到各零碎调用的次数,返回谬误次数,总提早,均匀提早等信息。

  4. 咱们也能够进一步剖析高提早的调用栈信息

    perf trace record --call-graph dwarf -p $PID -- sleep 10

  5. 对一组工作进行 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 环境。其原理比较简单,其架构如图所示:

外围步骤如下:

  1. 利用 bpf helper 获取 cgroup id,依据 cgroup id 而不是 pid、tid 进行过滤。
  2. 每个 cgroup id 对应一个 bpf tail call,通过这种形式实现对此 cgroup id 对应的 perf ring buffer 进行写入。
  3. 用户空间依据 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 会更不便一些。

正文完
 0