正文
(1)栈回溯方案分析
栈回溯主要是获取当前程序的完整调用栈,它是生成火焰图的首要且关键的步骤,这一过程中存在两个主要的技术挑战:
1. 无fp(frame pointer,帧指针)的应用程序:为了优化性能,众多程序选择不保留fp。这导致我们无法依赖传统的基于fp回溯的方法来获取调用栈信息。因此,我们必须转而采用基于dwarf的更为复杂的栈回溯技术。
2. Java、Python等解释型语言的栈回溯:这些解释型或高级编程语言各自拥有独特的栈帧结构。因此,关键在于识别当前运行的程序,并准确解析出相应的栈帧信息。
为了应对这两个挑战,Sysom利用eBPF的编程灵活性,支持无fp的应用以及解释型语言的栈回溯功能。除了eBPF,其他主流的栈回溯方案包括perf和语言级别的接口(例如Java提供的JVM TI)。以下是对这三种栈回溯方案的对比分析。
从上表中我们可以观察到不同方案各自的优势和局限性。
1)Perf作为一个历史悠久的性能分析工具,它支持所有版本的内核,但在处理动态语言方面表现不足。此外,当使用基于dwarf的栈回溯时,由于需要将整个用户态栈空间输出到用户态程序,这会导致较大的资源消耗。
2)eBPF的可编程性为新型栈回溯方案开辟了广阔的可能性,尤其是在支持动态语言栈回溯方面,通过分析代码运行时信息,能够完整解析出Java、Python等动态语言的调用栈,充分展现了eBPF的灵活性。唯一的限制是它对内核版本有一定的要求。
3)至于语言级别的采样工具,如async-profiler,它们能够利用JVM提供的接口来收集栈信息,不依赖于内核版本,且资源消耗较低。然而,由于它们是进程级别的侵入式采样,存在极低概率导致业务应用崩溃,因此在稳定性方面存在不足。
对于Sysom而言,其设计目标是能在生产环境中持续稳定运行。因此,在确保功能完整性的基础上,稳定性被视为最重要的因素。为了实现这一目标,Sysom集成了三种不同的方案,以便在各种场景下都能提供完善的功能支持。在底层的决策逻辑中,eBPF被设定为最优先选项,其次是perf,最后是语言级接口。下面的图表展示了根据不同编程语言和内核版本选择的栈回溯方案。
(2)符号解析方案分析
符号解析主要是将对应的地址转换成函数名,一般地,对于编译型语言的应用可以通过查找elf文件的符号表即可完成,对于解释型语言需要从进程内存中读取符号。这些是符号解析所需要解决的技术问题。从架构方案来看,存在两种方案选择:
从上表中可以观察到,本地符号解析依赖较少,由于需要进行符号缓存以加速查找速度,这会导致较大的内存占用。此外,由于大多数业务应用在生产环境中部署时不包含debuginfo,可能会出现符号缺失,进而影响符号的准确性。相比之下,远程符号解析的部署依赖会多些,例如依赖网络传输调用栈信息,但它不需要在业务机器上缓存符号,因此内存占用较低。同时,远程解析可以从类似yum源的地方下载应用的debuginfo包,以获得更完整的符号信息。
本地解析更适合于单台机器的性能剖析,而远程解析更适合于集群和大规模部署,能够显著降低整体开销。例如,如果集群内部署的是同一版本的MySQL应用,那么只需建立一个全局的符号缓存,从而减少资源消耗。鉴于本地和远程符号解析各有优势,Sysom同时支持这两种方案。
下面的架构图是由底层组件Coolbpf profiler至前端的完整系统结构,它由三个主要部分组成:控制台前端、Sysom Agent 和 Coolbpf profiler,其中SysOM是智能运维平台,Coolbpf是eBPF采集工具,Sysom Agent 负责启动Coolbpf功能及数据通信。
下面是对每个部分的详细介绍:
1)控制台前端:这是用户与系统交互的界面,提供了性能分析的可视化功能。包含三个主要功能模块:
2)Sysom Agent:作为中间层,Sysom Agent 负责收集和处理性能数据,并将结果发送到前端。包含四个热点模块:
-
OnCpu热点:检测CPU上的热点问题。
-
OffCpu热点:检测进程为什么被阻塞。
-
内存热点:识别内存使用中的热点区域。
-
锁热点:分析并报告锁竞争导致的性能问题。
3)Coolbpf profiler:这是底层的通用性能分析库,为Sysom Agent提供支持。包含两个主要部分: