返回顶部
首页 > 资讯 > 精选 >victoriaMetrics代理性能优化问题怎么解决
  • 757
分享到

victoriaMetrics代理性能优化问题怎么解决

2023-06-29 20:06:02 757人浏览 泡泡鱼
摘要

这篇文章主要介绍了victoriaMetrics代理性能优化问题怎么解决的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇victoriaMetrics代理性能优化问题怎么解决文章都会有所收获,下面我们一起来看看吧

这篇文章主要介绍了victoriaMetrics代理性能优化问题怎么解决的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇victoriaMetrics代理性能优化问题怎么解决文章都会有所收获,下面我们一起来看看吧。

起因

最近有做一个prometheus metrics代理的一个小项目,暂称为prom-proxy,目的是为了解析特定的指标(如容器、traefik、Istio等指标),然后在原始指标中加入应用ID(当然还有其他指标操作,暂且不表)。经过简单的本地验证,就发布到联调环境,跑了几个礼拜一切正常,以为相安无事。但自以为没事不代表真的没事。

昨天突然老环境和新上prom-proxy的环境都出现了数据丢失的情况,如下图:

victoriaMetrics代理性能优化问题怎么解决

prom-proxy有一个自服务指标request_total,经观察发现,该指标增长极慢,因而一开始怀疑是发送端的问题(这是一个误区,后面会讲为何要增加缓存功能)。

进一步排查,发现上游发送端(使用的是victoriaMetrics的vmagent组件)出现了如下错误,说明是prom-proxy消费的数据跟不上vmagent产生的数据:

2022-03-24T09:55:49.945Z        warn    VictoriaMetrics/app/vmagent/remotewrite/client.Go:277   couldn't send a block with size 370113 bytes to "1:secret-url": Post "xxxx": context deadline exceeded (Client.Timeout exceeded while awaiting headers); re-sending the block in 16.000 seconds

出现这种问题,首先想到的是增加并发处理功能。当前的并发处理数为8(即后台的goroutine数目),考虑到线上宿主机的core有30+,因此直接将并发处理数拉到30。经验证发现毫无改善。

另外想到的一种方式是缓存,如使用kafka或使用golang自带的缓存chan。但使用缓存也有问题,如果下游消费能力一直跟不上,缓存中将会产生大量积压的数据,且Prometheus监控指标具有时效性,积压过久的数据,可用性并不高又浪费存储空间。

下面是使用了缓存chan的例子,s.reqChan的初始大小设置为5000,并使用cacheTotal指标观察缓存的变更。这种方式下,数据接收和处理变为了异步(但并不完全异步)。

上面一开始有讲到使用request_total查看上游的请求是个误区,是因为请求统计和请求处理是同步的,因此如果请求没有处理完,就无法接收下一个请求,request_total也就无法增加。

func (s *Server) injectLabels(w Http.ResponseWriter, r *http.Request) {    data, _ := DecodeWriteRequest(r.Body)    s.reqChan <- data    cacheTotal.Inc()    w.WriteHeader(http.StatusNoContent)}func (s *Server) Start() {    go func() {        for data := range s.reqChan {            cacheTotal.Dec()            processor := s.pool.GetWorkRequest()            go func() {                processor.JobChan <- data                res := <-processor.RetChan                if 0 != len(res.errStr) {                    log.Errorf("err msg:%s,err.code:%d", res.errStr, res.statusCode)                    return                }            }()        }    }()}

上线后观察发现cacheTotal的统计增加很快,说明之前就是因为处理能力不足导致request_total统计慢。

至此似乎陷入了一个死胡同。多goroutine和缓存都是不可取的。

回顾一下,prom-proxy中处理了cadvisor、kube-state-metrics、istio和traefik的指标,同时在处理的时候做了自监控,统计了各个类型的指标。例如:

prom-proxy_metrics_total{kind="container"} 1.0396728e+07prom-proxy_metrics_total{kind="istio"} 620414prom-proxy_metrics_total{kind="total"} 2.6840415e+07

cacheTotal迅猛增加的同时,发现request_total增长极慢(表示已处理的请求),且istio类型的指标处理速率很慢,,而container类型的指标处理速度则非常快。这是一个疑点。

vmagent的一个请求中可能包含上千个指标,可能会混合各类指标,如容器指标、网关指标、中间件指标等等。

通过排查istio指标处理的相关代码,发现有三处可以优化:

  • 更精确地匹配需要处理的指标:之前是通过前缀通配符匹配的,经过精确匹配之后,相比之前处理的指标数下降了一半。

  • 代码中有重复写入指标的bug:这一处IO操作耗时极大

  • 将写入指标操作放到独立的goroutine pool中,独立于标签处理

经过上述优化,上线后发现缓存为0,性能达标!

一开始在开发prom-proxy之后也做了简单的benchmark测试,但考虑到是在办公网验证的,网速本来就慢,因此注释掉了写入指标的代码,初步验证性能还算可以就结束了,没想到埋了一个深坑。

所以所有功能都需要覆盖验证,未验证的功能点都有可能是坑!

总结

  • 服务中必须增加必要的自监控指标:对于高频率请求的服务,增加请求缓存机制,即便不能削峰填谷,也可以作为一个监控指标(通过Prometheus metric暴露的),用于观察是否有请求积压;此外由于很多线上环境并不能直接到宿主机进行操作,像获取火焰图之类的方式往往不可行,此时指标就可以作为一个参考模型。

  • 进行多维度度、全面的benchmark:代码性能分为计算型和IO型。前者是算法问题,后者则涉及的问题比较多,如网络问题、并发不足的问题、使用了阻塞IO等。在进行benchmark的时候可以将其分开验证,即注释掉可能耗时的IO操作,首先验证计算型的性能,在计算型性能达标时启用IO操作,进一步做全面的benchmark验证。

后续

喜闻乐见的后续来了。。。

由于公司有两个大的线上集群,暂称为more集群和less集群,很不幸,性能达标的就是less集群的,其指标数据相比more集群来说非常less,大概是前者的十分之一。上到more集群之后服务内存直接达到50G,多个副本一起吃内存,直接将节点搞挂了。

迫不得已(又是那句话,感觉对了的点往往不对),重新做了pprof压力测试,发现内存黑洞就是下面这个函数(来自Prometheus),即便在办公电脑下进行压测,其内存使用仍然达到好几百M。该函数主要是读取vmagent传来的请求,首先进行snappy.Decode解码,然后unmarshal到临时变量wr中。低流量下完全没有问题,但高流量下完全无法应对:

func DecodeWriteRequest(r io.Reader) (*ReqData, error) {compressed, err := ioutil.ReadAll(r)if err != nil {return nil, err}reqBuf, err := snappy.Decode(nil, compressed)if err != nil {return nil, err}var wr prompb.WriteRequestif err := proto.Unmarshal(reqBuf, &wr); err != nil {return nil, err}return &ReqData{reqBuf: reqBuf,wr:     &wr,}, nil}

解决办法就是拿出sync.pool大杀器,下面方式参考了victoriaMetrics的byteutil库(代码路径lib/byteutil),有兴趣的可以去看下,经过压测,相同测试情况下内存降到了不足100M。

func DecodeWriteRequest(r io.Reader, callback func(*prompb.WriteRequest)) error {ctx := getPushCtx(r)defer putPushCtx(ctx)if err := ctx.Read(); err != nil {return err}bb := bodyBufferPool.Get()defer bodyBufferPool.Put(bb)var err errorbb.B, err = snappy.Decode(bb.B[:cap(bb.B)], ctx.reqBuf.B)if err != nil {return err}wr := getWriteRequest()defer putWriteRequest(wr)if err := wr.Unmarshal(bb.B); err != nil {return err}callback(wr)return nil}

这样一来性能完全达标,10core下单pod每秒可以处理250w个指标!

重新发布线上,自然又出问题了,这次prom-proxy服务一切正常,但导致后端vmstorage(victoriametrics的存储服务)内存爆满。经过初步定位,是由于出现了slow insert,即出现大量 active time series导致缓存miss,进而导致内存暴增(prom-proxy服务会在原始指标中增加标签,并创建其他新的指标,这两类指标数目非常庞大,都属于active time series)。

victoriaMetrics代理性能优化问题怎么解决

victoriaMetrics代理性能优化问题怎么解决

最终的解决方式是将修改的指标作分类,并支持配置化启用,即如果修改的指标类型有:A、B、C、D四类。首先上线A,然后上线B,以此类推,让vmstorage逐步处理active time series,以此减少对后端存储的瞬时压力。

vmstorage有一个参数:--storage.maxDailySeries,它可以限制active time series的数目。但环境中正常情况下就有大量active time serials,如果设置了这个参数,新增的active time serials极有可能会挤掉老的active time serials,造成老数据丢失。

关于“victoriaMetrics代理性能优化问题怎么解决”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“victoriaMetrics代理性能优化问题怎么解决”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注编程网精选频道。

--结束END--

本文标题: victoriaMetrics代理性能优化问题怎么解决

本文链接: https://lsjlt.com/news/326353.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • victoriaMetrics代理性能优化问题怎么解决
    这篇文章主要介绍了victoriaMetrics代理性能优化问题怎么解决的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇victoriaMetrics代理性能优化问题怎么解决文章都会有所收获,下面我们一起来看看吧...
    99+
    2023-06-29
  • victoriaMetrics代理性能优化问题解析
    目录起因总结后续起因 最近有做一个Prometheus metrics代理的一个小项目,暂称为prom-proxy,目的是为了解析特定的指标(如容器、traefik、istio等指标...
    99+
    2024-04-02
  • Mysql索引性能优化问题解决方案
    mysql 创建的优化就是加索引,可是有时候会遇到加索引都没法达到想要的效果的情况, 加上了所以,却还是搜索的全数据,原因是sql EXPLAIN SELECT cs.sid, ...
    99+
    2022-05-11
    Mysql 索引 性能优化
  • PHP性能优化常见问题解答:轻松解决性能瓶颈!
    PHP是一种广泛使用的服务器端脚本语言,以其简单易学和跨平台性而著称。然而,随着网站和应用程序的日益复杂,PHP性能优化变得越来越重要。本文将介绍一些常见的PHP性能优化问题,并提供相应的解决方案。 程序架构设计不合理,数据库调用的优化...
    99+
    2024-02-05
    PHP 性能优化 瓶颈 代码 数据库 缓存
  • PHP 性能优化:常见问题与解决之道
    针对 php 性能优化常见问题,本文提供以下四大解决方案:优化数据库查询,通过创建索引、缓存常用查询结果和使用分页机制;使用缓存存储经常被访问的数据,并配置适当的缓存设置;优化数据结构、...
    99+
    2024-05-10
    php 性能优化 redis
  • sql server查询语句阻塞优化性能问题怎么解决
    这篇文章主要介绍“sql server查询语句阻塞优化性能问题怎么解决”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“sql server查询语句阻塞优化性能问题怎么解决”文章能帮...
    99+
    2023-06-29
  • Oracle 性能优化-trigger问题
    Oracle 性能优化-trigger问题 问题现象 : 谓词通过唯一性索引,更新一条记录,耗时很长; 通过 AWR 查看 TOP SQL ,这个UPDATE  SQ...
    99+
    2024-04-02
  • Hibernate性能问题怎么解决
    本篇内容主要讲解“Hibernate性能问题怎么解决”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Hibernate性能问题怎么解决”吧!在使用Hibernate进行分页的过程中,如果你收到如下...
    99+
    2023-06-17
  • 怎么用matlab代码解决单目标优化问题
    这篇“怎么用matlab代码解决单目标优化问题”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇...
    99+
    2024-04-02
  • React性能优化之非必要的渲染问题解决
    目录1. 非必要组件渲染2. 解决方案之 shouldComponentUpdate3. 解决方案之 PureComponent4. 解决方案之 React.memo5. ...
    99+
    2024-04-02
  • 凸优化:python解决凸优化问题
    1、凸优化 2、安装CVX包 用pip安装cvxpy-0.4.8-py2-none-any.whl 下载地址: http://www.lfd.uci.edu/~gohlke/pythonlibs/ 3、安装过程中可能遇到的...
    99+
    2023-01-31
    python
  • VUE SSR 性能优化:解决卡顿问题的一剂良方
    1. 减少服务器端渲染的组件数量 SSR 会在服务器端渲染整个应用程序,这会导致在某些情况下加载大量组件。为了优化性能,应尽量避免在服务器端渲染非必要的组件。 2. 使用代码分割 代码分割允许将应用程序拆分为更小的块,以便按需加载。这可以...
    99+
    2024-03-11
    Vue Server-Side Rendering (SSR) 可以显著提高 Vue.js 应用程序的初始加载性能。但是 如果不进行适当的优化 SSR 可能会导致应用程序卡顿 影响用户体验。
  • 怎么理解Scala循环性能问题
    这篇文章主要讲解了“怎么理解Scala循环性能问题”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么理解Scala循环性能问题”吧!最近我在学习我们产品的代码,看到了类似以下的一段代码:x....
    99+
    2023-06-16
  • vue终极性能优化方案(解决首页加载慢问题)
    目录前言1.路由懒加载2、打包文件中去掉map文件3、CDN引入第三方库4、gzip打包1、npm i -D compression-webpack-plugin2、在vue.con...
    99+
    2024-04-02
  • React性能优化之非必要的渲染问题如何解决
    这篇“React性能优化之非必要的渲染问题如何解决”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“React性能优化之非必要的...
    99+
    2023-07-02
  • 如何解决PHP开发中的性能瓶颈和优化问题
    在PHP开发过程中,性能瓶颈和优化问题是我们经常面对的挑战。一个高效的PHP应用程序可以提升用户体验,减少服务器负载,并节省成本。本文将探讨一些常见的性能瓶颈问题,并提供一些解决方案和代码示例。一、数据库查询优化数据库查询是PHP应用程序中...
    99+
    2023-10-21
    PHP开发 性能瓶颈 优化问题
  • golang接口性能低问题怎么解决
    要解决Golang接口性能低的问题,可以尝试以下几种方法: 使用具体类型而非接口类型:接口类型在运行时需要进行类型断言,会增加一...
    99+
    2023-10-23
    golang
  • Vite代理怎么解决跨域问题
    本篇内容主要讲解“Vite代理怎么解决跨域问题”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Vite代理怎么解决跨域问题”吧!Vite Proxy我们这里以 Vite 的配置为例,来看一下如何给...
    99+
    2023-07-05
  • matlab多元函数优化问题怎么解决
    在Matlab中,可以使用多种方法来解决多元函数优化问题。一种常用的方法是使用内置的优化函数fmincon。该函数可以用于求解有约束...
    99+
    2023-10-07
    matlab
  • matlab有约束最优化问题怎么解决
    在Matlab中,可以使用内置函数fmincon来解决约束最优化问题。fmincon函数的基本形式如下:x = fmincon(fu...
    99+
    2023-09-13
    matlab
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作