动态追踪(下)

perf

perf 的功能

  • perf 可以用来分析 CPU cache、CPU 迁移、分支预测、指令周期等各种硬件事件;
  • perf 也可以只对感兴趣的事件进行动态追踪
  • 先对事件进行采样,然后再根据采样数,评估各个函数的调用频率

perf例子

1.内核函数 do_sys_open 的例子

很多人只看到了 strace 简单易用的好处,却忽略了它对进程性能带来的影响。

从原理上来说,strace 基于系统调用 ptrace 实现,这就带来了两个问题:

  • 由于 ptrace 是系统调用,就需要在内核态和用户态切换。当事件数量比较多时,繁忙的切换必然会影响原有服务的性能;
  • ptrace 需要借助 SIGSTOP 信号挂起目标进程。这种信号控制和进程挂起,会影响目标进程的行为。

在性能敏感的应用(比如数据库)中,我并不推荐你用 strace (或者其他基于 ptrace 的性能工具)去排查和调试。

在 strace 的启发下,结合内核中的 utrace 机制, perf 也提供了一个 trace 子命令,是取代 strace 的首选工具。

相对于 ptrace 机制来说,perf trace 基于内核事件,自然要比进程跟踪的性能好很多。

 

第二个 perf 的例子是用户空间的库函数

# 为/bin/bash添加readline探针
$ perf probe -x /bin/bash 'readline%return +0($retval):string’

# 采样记录
$ perf record -e probe_bash:readline__return -aR sleep 5

# 查看结果
$ perf script
    bash 13348 [000] 93939.142576: probe_bash:readline__return: (5626ffac1610 <- 5626ffa46739) arg1="ls"

# 跟踪完成后删除探针
$ perf probe --del probe_bash:readline__return

 

eBPF 和 BCC

eBPF 就是 Linux 版的 DTrace,可以通过 C 语言自由扩展(这些扩展通过 LLVM 转换为 BPF 字节码后,加载到内核中执行)。

下面这张图,就表示了 eBPF 追踪的工作原理:

动态追踪(下)_第1张图片

 

 eBPF 的执行需要三步:

  • 从用户跟踪程序生成 BPF 字节码;
  • 加载到内核中运行;
  • 向用户空间输出结果

 

SystemTap 和 sysdig

SystemTap 也是一种可以通过脚本进行自由扩展的动态追踪技术。

在 eBPF 出现之前,SystemTap 是 Linux 系统中,功能最接近 DTrace 的动态追踪机制。不过要注意,SystemTap 在很长时间以来都游离于内核之外(而 eBPF 自诞生以来,一直根植在内核中)。

所以,从稳定性上来说,SystemTap 只在 RHEL 系统中好用,在其他系统中则容易出现各种异常问题。

当然,反过来说,支持 3.x 等旧版本的内核,也是 SystemTap 相对于 eBPF 的一个巨大优势。s

ysdig 则是随着容器技术的普及而诞生的,主要用于容器的动态追踪。

sysdig 汇集了一些列性能工具的优势,可以说是集百家之所长。

这个公式来表示 sysdig 的特点: sysdig = strace + tcpdump + htop + iftop + lsof + docker inspect

 

如何选择追踪工具

  1. 在不需要很高灵活性的场景中,使用 perf 对性能事件进行采样,然后再配合火焰图辅助分析,就是最常用的一种方法;
  2. 而需要对事件或函数调用进行统计分析(比如观察不同大小的 I/O 分布)时,就要用 SystemTap 或者 eBPF,通过一些自定义的脚本来进行数据处理

动态追踪(下)_第2张图片

 

你可能感兴趣的:(动态追踪(下))