关于Profiling的一些思考

当我们面对性能问题的时候,我们可以通过Profiling来帮助我们进行程序性能优化。

例如我们可以通过perf record命令来收集系统的调用栈信息,并将这个数据转换成火焰图从而发现系统性能热点;例如我们可以通过pprof来收集Go程序运行的Profiling信息,并同样将这个数据转换成火焰图来发现性能热点;例如我们可以通过pyroscope来展示调用栈信息,并进行两个调用栈之间的对比。

在本文之中,笔者将抛砖引玉,讨论Profiling的一些选择。其中如果有错误或者不准确的地方,欢迎各位读者指出,笔者将虚心改正。

持续还是按需?

最近一段时间,很多持续Profiling的工具逐渐出现,包括pprofDataDoggProfiler(Granulate)Pyroscope等。基于其使用方式,我们将它们粗浅的分为两类:

  • 按需使用:像perfpprof这样的工具,由用户手动触发,收集性能数据;
  • 持续Profiling:像gProfilerPyroscope等项目,都是采取agent上报数据的方式,不关注底层的收集器是什么,基于某一种数据格式持续上报,如下图所示:

对于按需使用,其场景往往是:我们已经通过一些信息发现系统有问题,接着复现场景,并基于工具进行按需采样。尤其是像perf这样的工具,其使用灵活性非常高,可以得到更多的信息,往往由用户直接在命令行进行操作。

而对于按需使用而言,用户并不关注命令行的信息,而只关注agent持续上报后的信息,当发现某个时间段有问题的时候,可以快速的去查看,无需再准备场景,直接就可以获取已经上报的信息,从而发现问题;此外,长时间的Profiling可以帮助我们更深刻的了解负载的运行,但是可能会隐藏一些毛刺信息。

按需采样的缺点在于我们需要去做场景的复刻,以及需要更多的人工介入;而持续采样则与之相反,一切都已在数据中,面对需要但没有上报的数据时也会遇到按需采样的问题,此外,过多的数据也会成为持续采样的诅咒:采了这么多数据,到底哪些是有用的?

那么,哪一种方式好一些呢?个人认为一切都应该以解决问题 为出发点,辅以效率和成本的trade off。当然,我们也可以结合两者的优点,完成按需的数据上报实现,这样可能更有助于使用,但是同时也会继承两者的缺点。

数据模型

在最近,OpenTelemetry 社区正在进行关于Profiling数据模式的讨论,由Pyroscope的工程师提交了一份PR。在这个提案中,作者尝试给OpenTelemetry加了除了LogTraceMetris之外的数据模式:

作为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目录下查看信息;我们还可以知道其数据格式可以做哪些转换和展示:

如果你不了解某一些格式,或者想尝试将某种格式进行转换,可以尝试查看该项目,以便获取到更多信息。

参考资料

相关推荐
许野平1 小时前
Rust: 利用 chrono 库实现日期和字符串互相转换
开发语言·后端·rust·字符串·转换·日期·chrono
萌面小侠Plus3 小时前
Android笔记(三十三):封装设备性能级别判断工具——低端机还是高端机
android·性能优化·kotlin·工具类·低端机
齐 飞3 小时前
MongoDB笔记01-概念与安装
前端·数据库·笔记·后端·mongodb
LunarCod3 小时前
WorkFlow源码剖析——Communicator之TCPServer(中)
后端·workflow·c/c++·网络框架·源码剖析·高性能高并发
码农派大星。4 小时前
Spring Boot 配置文件
java·spring boot·后端
杜杜的man4 小时前
【go从零单排】go中的结构体struct和method
开发语言·后端·golang
幼儿园老大*4 小时前
走进 Go 语言基础语法
开发语言·后端·学习·golang·go
llllinuuu4 小时前
Go语言结构体、方法与接口
开发语言·后端·golang
cookies_s_s4 小时前
Golang--协程和管道
开发语言·后端·golang
为什么这亚子5 小时前
九、Go语言快速入门之map
运维·开发语言·后端·算法·云原生·golang·云计算