ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

prometheus PromSQL使用小技巧

2021-02-27 17:32:58  阅读:2325  来源: 互联网

标签:count 技巧 request PromSQL prometheus deployment test pod revision


前言

这个礼拜一面在找那个CrashLoopBackoff的原因,另一个是在尝试修复es报错Data too large的问题,还有一个任务就是解析告警规则了,因为新需求加了很多类型的告警,支持的维度也更多了,我们的告警使用的Prometheus + Alertmanager,之前的几篇博客也提到过,这里主要想记录一下我在解析规则这里,遇到的一些问题以及解法。

抛出问题

Counter类型计算过去一个时间段内的增量

举例问题:计算revision_request_count过去五分钟的请求次数?
问题分析:revision_request_count是queue-proxy上报的指标,用于记录knative创建的pod请求次数,熟悉Prometheus的同学都知道,prometheus有四种数据类型,其中counter是只增不减的,比如http请求次数,一分钟内请求一次是1,第二分钟再请求一次是2,然后第三分钟一直不请求,那么值就一直是2,这时候在第四分钟的时刻,计算过去一分钟内,请求的次数,就是0。首先遇到问题不要怕,翻开Promemtheus的官方手册可以看见有个函数叫做increase(),可以计算counter类型过去时间的增量
解法:

increase(revision_request_count{pod=~"api.*"}[5m])

PromSQL是支持正则的,因此可以使用正则表示式的语法,这里使用了约等于。同时需要注意一点的是,incease()函数是基于rate()函数得来的,因此这里可能会有小数点的情况,因此,可以使用round()函数进行取整:

round(increase(revision_request_count{pod=~"api.*"}[5m]))

Counter类型画增量折线图

举例问题:查询revision_request_count过去一小时内,每五分钟的请求次数?
分析:这个问题是可以在上一个问题的基础上引申,上面已经做到了对过去5分钟的请求次数,这里只需要为这个过去指定一个时刻,就可以计算出一个小段一个小段的值。promehteus的查询语句分为两种,一种是query,一种是query_range,query_range的语法:

curl 'http://localhost:9090/api/v1/query_range?query=up&start=2015-07-01T20:10:30.781Z&end=2015-07-01T20:11:00.781Z&step=15s'

那么问题的答案也出来了
答案:

query_range?query=round(increase(revision_request_count{pod=~"api.*"}[5m]))&start=2021-02-27T16:00:00.000Z&end=2021-02-27T17:00:00.000Z&step=5m'

注意这里的step=5m需要和[5m]保持一值。

根据已有标签,按规则增加新的标签

举例问题:由于knative带有扩容特性,使用了kpa或者hpa都可以对pod按照cpu或者concurrency进行扩容,也就是会生成许多类似于如下这样的pod:

test-001-deployment-bf7dc8f95-xadjk
test-001-deployment-bf7dc8f95-gfd5b
test-001-deployment-bf7dc8f95-mgxtv
test-002-deployment-5fcfdbfc4-xx6cs
test-002-deployment-5fcfdbfc4-bw6rd
test-003-deployment-68f88c67c-6ng7n
test-003-deployment-68f88c67c-aferd

其中test为服务名称,001表示第一个版本,002表示第二个版本,003表示为第三个版本,deployment是自定义的后缀,第一个随机段是replicaset的标识,第二个随机段是pod的标识,
那么revison_request_count的值就会是这样的:

revision_request_count(pod="test-001-deployment-bf7dc8f95-xadjk", namespace="test")
revision_request_count(pod="test-001-deployment-bf7dc8f95-gfd5b", namespace="test")
revision_request_count(pod="test-001-deployment-bf7dc8f95-mgxtv", namespace="test")
revision_request_count(pod="test-002-deployment-5fcfdbfc4-xx6cs", namespace="test")
revision_request_count(pod="test-002-deployment-5fcfdbfc4-bw6rd", namespace="test")
revision_request_count(pod="test-003-deployment-68f88c67c-6ng7n", namespace="test")
revision_request_count(pod="test-003-deployment-68f88c67c-aferd", namespace="test")

需求是能够按照不同版本或者不同服务对revision_request_count进行聚合
分析:这里想到的第一个解决方式是使用group分组(Java的stream用的太多的后遗症),而prometheus也有相应用法,比如 sum by (namespace, pod)(),但这里by的是label,无法支持正则分组,因次此法不通。一度难倒我了,有点儿手足无措的感觉,不过还好我翻看prometheus官方文档的时候,找到这样一个函数label_replace(),可以将label按照正则表达式切分,然后取其中的一段,作为新的标签加入到指标中。举例:

label_replace(revision_request_count{namespace="test",container="user-container", pod=~"test.deployment.*|.*"}[5m]), "service","$1","pod","(.*).[0-9]{3}.deployment.*")

解释一下,label_replace()函数,会对pod标签,按照 "(.*).[0-9]{3}.deployment.*"模式进行匹配,如果匹配不到,则无变化,如果匹配到了,那么就将service=$1(正则匹配的第一个串,这里是test)加入到label中,在本例中,也就是会增加service=test这个标签。细心的小伙伴会发现,pod=~“test.deployment.*|.*”,这里使用了竖线|这个语法是指或者的意思,约等于a,或者约定于b,取的是并集。同时支持正则,如果使用.*则标识所有,注意不是一个星*,而是.*,这里只是演示|的作用。
返回的结果:可以看见增加了一个标签

revision_request_count(service="test", pod="test-001-deployment-bf7dc8f95-xadjk", namespace="test")
revision_request_count(service="test", pod="test-001-deployment-bf7dc8f95-gfd5b", namespace="test")
revision_request_count(service="test", pod="test-001-deployment-bf7dc8f95-mgxtv", namespace="test")
revision_request_count(service="test", pod="test-002-deployment-5fcfdbfc4-xx6cs", namespace="test")
revision_request_count(service="test", pod="test-002-deployment-5fcfdbfc4-bw6rd", namespace="test")
revision_request_count(service="test", pod="test-003-deployment-68f88c67c-6ng7n", namespace="test")
revision_request_count(service="test", pod="test-003-deployment-68f88c67c-aferd", namespace="test")

以上是对服务进行聚合的,要对于服务的不同版本聚合,可以稍微更改一下正则表达式

label_replace(revision_request_count{namespace="test",container="user-container", pod=~"test.deployment.*|.*"}[5m]), "service","$1","pod","(.*).deployment.*")

数据就是这样的:可以看见增加了一个标签revision

revision_request_count(revision="test-001", pod="test-001-deployment-bf7dc8f95-xadjk", namespace="test")
revision_request_count(revision="test-001", pod="test-001-deployment-bf7dc8f95-gfd5b", namespace="test")
revision_request_count(revision="test-001", pod="test-001-deployment-bf7dc8f95-mgxtv", namespace="test")
revision_request_count(revision="test-002", pod="test-002-deployment-5fcfdbfc4-xx6cs", namespace="test")
revision_request_count(revision="test-002", pod="test-002-deployment-5fcfdbfc4-bw6rd", namespace="test")
revision_request_count(revision="test-003", pod="test-003-deployment-68f88c67c-6ng7n", namespace="test")
revision_request_count(revision="test-003", pod="test-003-deployment-68f88c67c-aferd", namespace="test")

按照版本聚合

这里需要基于上面那个例子,不过指标名称可能会发生少许变化,revsion_request_count改成kube_pod_container_status_running,正在运行的实例数,细心的小伙伴会发现这里使用到了一个函数,max_over_time(),这里是取过去一段时间内最大的值,相应的还有max_over_time(),avg_over_time(),感兴趣的小伙伴可以可以参考官方文档

sum by(revision)(label_replace(max_over_time(kube_pod_container_status_running{namespace="test", pod=~"test.[0-9]{3}.deployment.*|.*"}[5m]), "revison","$1","pod","(.*).deployment.*"))

按照服务聚合

这时候就可以按照服务名进行聚合了,比如:

sum by(service)(label_replace(max_over_time(kube_pod_container_status_running{namespace="test", pod=~"test.[0-9]{3}.deployment.*|.*"}[5m]), "service","$1","pod","(.*).[0-9]{3}.deployment.*"))

后记

其实knative中还有许许多多的指标,比如:
可以按照http状态码拿到不同服务的访问次数:

sum by (revision_name)(sum_over_time(revision_request_count{namespace="test",service_name=~"test",revision_name=".*", response_code=~"302|304"}[5m]))

拿到服务过去5分钟内的由于oom导致的重启次数:

sum by (service)(label_replace(sum_over_time(kube_pod_container_status_terminated_reason{namespace=~test,pod=~".*",container="user-container",reason="OOMKilled"}[5m]), "service","$1","pod","(.*).[0-9]{3}.deployment.*"))

拿到某服务某版本过去5m cpu使用率:

sum by (revision)(label_replace(max_over_time(pod_cpu_limit_usage{namespace="test",pod=~".*"}[5m]),"revision","$1", "pod","(.*).deployment.*"))

拿到某服务某版本过去5m memory使用率:

sum by (revision)(label_replace(max_over_time(pod_memory_limit_usage{namespace="test",pod=~".*"}[5m]),"revision","$1", "pod","(.*).deployment.*"))

prometheus能拿到的信息简直是太多了,我这里只是列举了我工作中常用到的一些指标,希望对大家有所帮助。

标签:count,技巧,request,PromSQL,prometheus,deployment,test,pod,revision
来源: https://blog.csdn.net/u012803274/article/details/114176914

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有