go runtime/pprof,net/http/pprof:提高delta分析的效率和正确性

qmelpv7a  于 6个月前  发布在  Go
关注(0)|答案(9)|浏览(175)

提案详情

问题

在Golang中,分配、互斥锁和阻塞分析是累积的。它们只会随着时间的推移而增长,并显示自程序开始运行以来发生的分配/阻塞情况。不仅值会增长,而且分析本身的大小也会增长。对于长时间运行的进程,它可能会增长到兆字节的大小。
在许多情况下,查看两个时间点之间的差异更有用。你可以使用net/http/pprof包中的delta分析。使用delta分析需要将秒参数传递给pprof端点查询。

这个过程如下:

  1. 转储分析 p0
  2. 休眠
  3. 转储分析 p1
  4. 解压缩并解析protobuf p0
  5. 解压缩并解析protobuf p1
  6. p0 中减去 p1
  7. 序列化protobuf并压缩结果
    生成的分析通常要小得多(p0 可能达到兆字节,而压缩后的结果通常只有几十千字节)。这种方法存在一些问题:
  8. 堆分析包含分配值和已使用的值。已使用的值不是累积的。通过减法操作,已使用的值会被破坏。**注意:**如果net/http/pprof包使用p0.ScaleN([]float64{-1,-1,0,0})而不是p0.Scale(-1)来处理内存分析,那么这可以修复分配值和将已使用的值归零的问题——这样就可以从p0中减去分配值。
  9. 它需要转储两个大分析。
  10. 它会产生很多分配,给GC带来压力。

DataDog的fastdelta

DataDog的fastdelta分析器采用了另一种方法。它通过保留先前分析的副本并从中减去当前分析来改进运行时/pprof方法。fastdelta分析器使用自定义的protobuf pprof解析器,不会分配太多内存。这种方法更高效、更快,对GC的压力也更小。它还不需要使用两个分析。然而,fastdelta分析器仍然会解析高达兆字节的巨大分析,只是为了丢弃大部分内容。

Grafana的godeltaprof

godeltaprof执行类似的任务,但略有不同。增量计算发生在使用runtime.MemprofileRecordBlockProfileRecord序列化任何pprof文件之前。这样,巨大的分析就不需要被解析了。增量是在原始记录上计算的,所有零都被拒绝,结果被序列化和压缩。godeltaprof的源代码基于(分叉)原始代码。godeltaprof经过修改,包括在序列化之前进行增量计算,并公开新的端点。godeltaprof依赖于一系列golang运行时内部函数,特别是runtime_FrameStartLineruntime_FrameSymbolNameruntime_expandFinalInlineFrameruntime_cyclesPerSecondlink以及可能还有更多的内部函数。由于#67401的原因,依赖于内部函数变得越来越困难和危险。

建议

我们建议允许高效的增量内存、互斥锁和阻塞分析收集,既可以在runtime/pprof用于推送集成,也可以在net/http/pprof用于抓取集成。以下是改进的关键点:

  • 它不应该要求转储两个分析
  • 它不应该要求解压缩和解析pprof
  • 增量内存分析应该是正确的(要么未使用的值没有被破坏,要么将alloc_*和x2m20n20值放入单独的分析中)
ni65a41a

ni65a41a2#

哦,这可能是#57765的某种重复。

wd2eg0qa

wd2eg0qa3#

我不认为这需要成为一个提案(除非你认为新的运行时/pprof API是实现这个功能所必需的?),因此将其从提案过程中移除。

k7fdbhmy

k7fdbhmy4#

堆分析包含分配值和使用值。使用值不是累积的。使用值会受到减法操作的破坏。
注意:如果net/http/pprof包使用p0.ScaleN([]float64{-1,-1,0,0})代替p0.Scale(-1)来生成内存分析报告,那么可以修复这个问题——这将从分配值中减去使用值并将使用值清零。
我建议为此问题单独提交一个issue,如果还没有的话。本问题的其余部分是性能优化,但这是一个真正的bug。

c2e8gylq

c2e8gylq6#

我不知道,这对我来说似乎是一个新的API。(这是一个新的URL处理程序变体,但那仍然是API。)如果它最终成为一个非平凡的更改,请务必将其提交给提案流程。

zyfwsgd6

zyfwsgd67#

这是一个新的URL处理器变体,但仍然是API。也许我遗漏了什么,但我不了解这个新的URL处理器变体是什么。根据我的理解,这个问题的核心是使existing/debug/pprof/heap?seconds=30处理器更高效。

33qvvth1

33qvvth18#

也许我错过了,但我没有看到新的URL处理器变体是什么。我有几个想法:

  1. 改进/debug/pprof/heap?seconds=30(不知道API)。这仅修复了net/http/pprof包的问题,但不解决runtime/pprof的问题。
  2. 也许一个新的增量实现可以隐藏在runtime/pprof.Profile后面(新的API-配置文件名称,新的URL),这样它就可以解决net/http/pprofruntime/pprof包的问题。如果能有一个选项避免在收集配置文件时休眠,而是重用之前收集的数据,那就太好了。
gcmastyq

gcmastyq9#

我建议为这个问题单独提交一个,如果还没有的话。本问题的其余部分是性能优化,但这是一个真正的错误。
我认为已经存在一个问题 #57765 。尽管它没有错误标签

相关问题