bpftrace On-CPU 采样

profile 探针按频率对运行中的 CPU 采样, 快速得到按栈的 CPU 占比。

在处理器上的采样

按固定频率对运行中的处理器采样,记录当时的调用栈,得到按栈聚合的次数占比。它是轻量版的采样分析:不需要落盘再出报告,表达式里就能加上过滤条件,适合快速看分布,或者在正式分析前先确认方向。

基本信息

适用平台Linux,需要内核 eBPF 支持与相应权限
采样频率由探针的频率参数决定
输出形态按栈聚合的计数,可重定向到文件
栈类型可使用用户态栈、内核栈或二者组合
过滤方式表达式内的条件过滤

典型使用场景

  • 快速查看某个服务的用户态热点分布。
  • 按进程名过滤,只保留关心的对象。
  • 与正式采样工具的结果交叉印证,确认结论一致。
  • 输出到文件后再做聚合统计,避免刷屏。
  • 在资源受限的环境里做轻量观测,避免安装额外工具。

采样

采样
bpftrace -e 'profile:hz:99 /comm == "nginx"/ { @[ustack] = count(); }' > /tmp/prof.txt   # 指定进程用户态栈
bpftrace -e 'profile:hz:99 { @[kstack] = count(); }' > /tmp/kprof.txt                 # 内核栈分布
bpftrace -e 'profile:hz:49 { @[ustack(10)] = count(); }' > /tmp/prof10.txt             # 限制栈深度
bpftrace -e 'profile:hz:99 /pid == 12345/ { @[ustack] = count(); }'                    # 按进程号过滤
head -30 /tmp/prof.txt                                                                # 先看聚合结果的规模

写法与效果

写法要点效果注意
指定频率决定采样密度与开销先低频试跑
指定栈类型用户态、内核栈或组合栈越全开销越大
条件过滤减少输出内容采样成本不会因此降低
限制栈深度降低输出体量过浅会丢掉上层调用
输出到文件便于聚合与留档注意文件体积
输出是聚合计数而非原始样本,适合快速判断;需要火焰图时改用能直接输出折叠格式的工具,或把结果按折叠格式转换后再渲染,两种方式得到的图形可比性有限。
与基于内核自带采样工具的流程相比,这里的优势是表达式内即可加条件、无需落盘再出报告,适合边看边调整;正式归档与团队评审仍建议用可复现的采集脚本。
栈采集会显著放大开销,且过滤条件在采样之后生效——也就是说即使只关心一个进程,采样成本仍然按全系统发生,高频生产环境务必先小窗口试跑。

易错点

  • 栈采集放大开销,未先小窗口试跑就在生产环境长时间运行。
  • 误以为加了过滤条件就只采样目标进程,实际采样成本依旧覆盖全系统。
  • 栈深度设置过大,输出体量与实际可读性都变差。
  • 把聚合计数当成精确的耗时占比,忽略了采样频率与窗口的影响。
  • 输出直接刷屏不留档,事后无法复盘。

数据来源与参考

  • bpftrace 官方文档
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌