引
当我们面对性能问题的时候,我们可以通过Profiling
来帮助我们进行程序性能优化。
例如我们可以通过perf record
命令来收集系统的调用栈信息,并将这个数据转换成火焰图从而发现系统性能热点;例如我们可以通过pprof
来收集Go
程序运行的Profiling
信息,并同样将这个数据转换成火焰图来发现性能热点;例如我们可以通过pyroscope
来展示调用栈信息,并进行两个调用栈之间的对比。
在本文之中,笔者将抛砖引玉,讨论Profiling
的一些选择。其中如果有错误或者不准确的地方,欢迎各位读者指出,笔者将虚心改正。
持续还是按需?
最近一段时间,很多持续Profiling
的工具逐渐出现,包括pprof
、DataDog
、gProfiler(Granulate)
、Pyroscope
等。基于其使用方式,我们将它们粗浅的分为两类:
- 按需使用:像
perf
、pprof
这样的工具,由用户手动触发,收集性能数据; - 持续
Profiling
:像gProfiler
、Pyroscope
等项目,都是采取agent
上报数据的方式,不关注底层的收集器是什么,基于某一种数据格式持续上报,如下图所示:
对于按需使用,其场景往往是:我们已经通过一些信息发现系统有问题,接着复现场景,并基于工具进行按需采样。尤其是像perf
这样的工具,其使用灵活性非常高,可以得到更多的信息,往往由用户直接在命令行进行操作。
而对于按需使用而言,用户并不关注命令行的信息,而只关注agent
持续上报后的信息,当发现某个时间段有问题的时候,可以快速的去查看,无需再准备场景,直接就可以获取已经上报的信息,从而发现问题;此外,长时间的Profiling
可以帮助我们更深刻的了解负载的运行,但是可能会隐藏一些毛刺信息。
按需采样的缺点在于我们需要去做场景的复刻,以及需要更多的人工介入;而持续采样则与之相反,一切都已在数据中,面对需要但没有上报的数据时也会遇到按需采样的问题,此外,过多的数据也会成为持续采样的诅咒:采了这么多数据,到底哪些是有用的?
那么,哪一种方式好一些呢?个人认为一切都应该以解决问题 为出发点,辅以效率和成本的trade off
。当然,我们也可以结合两者的优点,完成按需的数据上报实现,这样可能更有助于使用,但是同时也会继承两者的缺点。
数据模型
在最近,OpenTelemetry
社区正在进行关于Profiling
数据模式的讨论,由Pyroscope
的工程师提交了一份PR。在这个提案中,作者尝试给OpenTelemetry
加了除了Log
、Trace
和Metris
之外的数据模式:
作为OpenTelemetry
这样一个可观测领域的顶级开源项目,一个新的类别协议的引入还是需要一些时间的。Profiling
的诸多工具都有属于自己的数据模式,例如perf
会生成perf.data
,我们可以用其自带的script
等功能进行解析;例如pprof
有定义好的proto
文件,并且可以将其数据输出成多种格式。
其实业界有诸多数据模式来描述Profiling
信息,那我们该如何设计一个数据模型呢?pyroscope
的工程师在提案之中提到了设计的目标:
-
Make profiling compatible with other signals:能够和
OpenTelemetry
的其他信号配合 -
Standardize profiling data model for industry-wide sharing and reuse:能够业界范围内分享和复用
-
Profilers must be able to be implementable with low overhead and conforming to OpenTelemetry-wide runtime overhead / intrusiveness and wire data size requirements:能够低开销的实现
对于设计工具的数据模型而言,个人认为应当遵循如下的一些标准:
- 实现简单,低开销:我们希望我们的数据模型应该能够被简单的记录和实现,而不需要有复杂的计算或者转换的步骤。在实际的场景中,当我们将一个工具或者
agent
部署到生产环境上的时候,我们总会被挑战这是否是开销低的,开销比较高的工具往往是不能被接受的,除非比较紧急; - 存储占用小:例如在
perf
的使用中,一旦遇到长时间使用的情况,我们会发现script
出来的未折叠数据量是非常大的; - 能够被其他语言/工具使用:现阶段的
Profiling
工具,不论是收集器还是可视化工具都是非常多的,在这样一个混沌的阶段,如果没有一个标准,那么就最好能够做好数据格式的转换,或者能够被快速的反序列化成结构数据;
对于OpenTelemetry
的新提案,笔者也会持续关注,也许未来社区将会出现一个较为大一统的Profiling
数据模型。
profilerpedia
在笔者了解Profiling
数据模型的过程中,发现了一个宝贵的开源项目,可以快速的帮助我们了解关于Profiling
的各种组件:
- Profiler:采样器,如
perf
; - Format:采集以后的数据格式,如
perf.data
; - Converter:不同数据格式之间的转换器;
- Analysis UI:用于可视化
Profiling
数据的组件;
对于每一个其中的组件,该项目都将相关的信息做了图形化的展示,如下图所示:
例如对于采样器Perf Record
而言,我们可以知道其采样以后得到的数据格式是Linux perf.data
,如果想了解这个数据格式,则可以进入到Format/Linux perf.data
目录下查看信息;我们还可以知道其数据格式可以做哪些转换和展示:
如果你不了解某一些格式,或者想尝试将某种格式进行转换,可以尝试查看该项目,以便获取到更多信息。