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

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

参考资料

相关推荐
·云扬·5 分钟前
MySQL中count(*)深度解析与性能优化实践
数据库·mysql·性能优化
Java水解9 分钟前
Spring Boot 配置文件深度解析
spring boot·后端
狗头大军之江苏分军15 分钟前
Node.js 性能优化实践,但老板只关心是否能跑
前端·后端
李拾叁的摸鱼日常24 分钟前
Java泛型基本用法与PECS原则详解
java·后端·面试
狗头大军之江苏分军24 分钟前
Node.js 真香,但每次部署都想砸电脑
前端·javascript·后端
帅那个帅1 小时前
go的雪花算法代码分享
开发语言·后端·golang
酒酿萝卜皮1 小时前
Elastic Search 聚合查询
后端
程序员清风1 小时前
阿里二面:新生代垃圾回收为啥使用标记复制算法?
java·后端·面试
sino爱学习1 小时前
Java 三元表达式(?:)的常见坑总结
java·后端