AutoProfiling - 新增 Off-CPU 持续剖析并支持 AI 智能体分析
2024-06-17本文为 DeepFlow v6.5 的企业版新功能:
- AutoProfiling 在 v6.5 中增加了对 Off-CPU 的支持,可用于排查业务性能不达预期但 CPU 用量却不高的问题。
- v6.5 中也增加了 Stella (DeepFlow 的 AI 智能体)对持续剖析数据的分析能力。
0x0: Off-CPU Profiling 的作用
Off-CPU 从字面上来看,表达的是「进程不在 CPU 上运行」,也可理解成进程等待被 CPU 调度。进程等待 CPU 调度的原因有多种,例如网络 I/O、磁盘 I/O、锁、睡眠等。利用 eBPF 技术,我们可以零侵扰的观测到任意进程在等待 CPU 的时间,即 Off-CPU 的时间。Brendan Gregg 博客上的这篇文章 Off-CPU Analysis,详细介绍了 Off-CPU 数据的采集、展示、分析方法。
Generic thread states (https://www.brendangregg.com/)
利用 Off-CPU 剖析数据,我们可以绘制类似 On-CPU 的火焰图,区别在于此时火焰图中 Span 的宽度表达的含义是等待被 CPU 调度的耗时,而对应的函数栈表示进程进入等待状态时的函数调用栈。
0x1: DeepFlow 中的 Off-CPU Profiling
目前,DeepFlow 已经支持了如下语言的 On-CPU、Off-CPU Profiling:
- 编译为 ELF 格式可执行文件的语言:Golang、Rust、C、C++
- 使用 JVM 虚拟机的语言:Java
使用 eBPF 零侵扰获取 Profiling 数据需满足两个前提条件:
- 进程需要开启 Frame Pointer(帧指针寄存器)
- 编译 Golang:默认开启,无需额外编译参数
- 编译 C/C++:
gcc -fno-omit-frame-pointer
- 编译 Rust:
RUSTFLAGS="-C force-frame-pointers=yes"
- 运行 Java:
-XX:+PreserveFramePointer
- 对于编译型语言的进程,编译时需要注意保留符号表
对于 Off-CPU Profiling 功能,目前 DeepFlow 仅会采集如下函数调用栈:
- 让出 CPU 时进程状态等于
TASK_INTERRUPTIBLE
(可中断睡眠)或TASK_UNINTERRUPTIBLE
(不可中断睡眠)的调用栈。这使得我们可以不去关注不重要的进程调度,降低采集的数据量。 - 0 号进程(Idle 进程)以外的调用栈
- 含有至少一个用户态函数的调用栈
- 等待 CPU 的时间不超过 1 小时的调用栈
eBPF Off-CPU Profiling 是默认开启的,但你需要通过修改 static_config
.ebpf
.off-cpu-profile
.regex
来指定需要启用的进程列表。默认情况下仅对进程名以 deepflow-
开头的进程开启。Agent 支持的配置参数如下:
1 | static_config: |
上述配置的含义如下:
- disabled:默认为 False,表示功能开启。
- regex:开启 Off-CPU Profiling 的进程名正则表达式。
- cpu:默认为 0,表示一台主机上采集的数据不区分 CPU,当设置为 1 时数据将按 CPU ID 聚合。
- minblock:使用持续时间限制采集的 Off-CPU 事件,避免采集过多导致主机负载过高。
以 deepflow-server 进程为例,下图是 DeepFlow 企业版中的展示效果:
deepflow-server Off-CPU 火焰图
Off-CPU 火焰图的特殊之处在于,由于等待 CPU 的函数是固定的,因此如上图所示左侧表格中自身消耗被 finish_task_switch
这个函数垄断。为了解决此问题,我们为火焰图增加了内核函数栈过滤能力。如下图所示,当隐藏所有内核函数时,我们能更加清晰的看到用户态函数等待 CPU 的热点情况:
忽略内核函数后的 deepflow-server Off-CPU 火焰图
0x2: 使用 Stella 分析剖析数据
v6.5 中,DeepFlow 智能体 Stella
可以对持续剖析数据进行智能分析。例如,对下图中一个 Golang 应用的 On-CPU 火焰图进行分析,可以得到非常专业的分析结果和建议:
Golang 应用的 On-CPU 火焰图
Stella 对 On-CPU 剖析数据的分析
我们可以看到,Stella 已经支持了对话,支持了问题建议,并支持读取 Git Repo 分析代码并给出代码修改建议。
0x3: 持续剖析的演进方向
在接下来的版本中,零侵扰持续剖析计划增加的能力包括:
- 消除对 Frame Pointer 的依赖
- 消除对符号表的依赖
- Java/Rust/… 等语言的 Memory Profiling
- Python/Lua/… 等其他语言的 Profiling
- GPU Profiling
- HBM (GPU High Bandwith Memory) Profiling
0x4: 什么是 DeepFlow
DeepFlow 是云杉网络开发的一款可观测性产品,旨在为复杂的云原生及 AI 应用提供深度可观测性。DeepFlow 基于 eBPF
实现了应用性能指标、分布式追踪、持续性能剖析等观测信号的零侵扰(Zero Code
)采集,并结合智能标签(SmartEncoding
)技术实现了所有观测信号的全栈(Full Stack
)关联和高效存取。使用 DeepFlow,可以让云原生及 AI 应用自动具有深度可观测性,从而消除开发者不断插桩的沉重负担,并为 DevOps/SRE 团队提供从代码到基础设施的监控及诊断能力。
GitHub 地址:https://github.com/deepflowio/deepflow
访问 DeepFlow Demo,体验零侵扰、全栈的可观测性。