01
背景
02
排查
分析指标数据查询接口和监控图表的对应关系后发现,监控图表加载失败是查询接口超时所导致的。使用超时的指标查询语句直接查询 Prometheus,即便将采样步长调高到40分钟,查询响应耗时依然有48秒之多。说明查询的主要耗时都用在 Prometheus 的查询处理上。
Prometheus查询处理流程分析
想要继续弄清楚 Prometheus 的查询处理为什么需要耗时这么久,我们需要简单了解一下 Prometheus 的查询处理流程。Prometheus 使用了一个基于标签(label)、值和时间戳的简单数据模型,这些标签和样本一起构成了数据序列(series),每个样本都是由时间戳和值组成。
Prometheus 将这些数据存储在其内部的时间序列数据库中(Prometheus 也支持外部存储系统)。Prometheus 的数据库被划分为基本的存储单元,称为 block,其中包含一定时间范围(默认2小时)的数据。block 的结构如下图所示:
postings index:保存着标签与包含该标签的序列之间的对应关系。例如,标签 __name__ ="logback_events_total" 可以被包含在两个序列中,logback_events_total {job="app1", level="error"}和 logback_events_total {job="app2", level="error"}。 series index:保存着序列和 chunk 之间的对应关系。例如,序列 {__name__=”logback_events_total”, job=”app1”, level="error"} 可能保存在00001和00002两个 chunk 里。
详细排查
执行如下 PromQL(Prometheus自定义的数据查询语言) 来查询该指标每个标签的基数(用实际标签名替换下面语句中的 label_name):
该指标的标签基数汇总如下:
可以看到,instance 和uri 这两个标签的基数都很高。执行如下 PromQL 查询该指标的基数,发现该指标的基数达到了147610。
用同样的方式分析了下其他问题指标,指标基数同样达到了10万以上。作为对比,我们抽样分析了几个加载比较快的指标,指标基数大都在1万以下。因此可以确认,查询耗时高主要是指标基数过高引起的。实际监控图表配置的查询语句中还使用了一些聚合操作(例如 sum)和内置函数(例如 rate),也在一定程度上增加了查询耗时。
03
优化
Prometheus 提供了一种叫做记录规则(Recording Rule)的方式来优化我们的查询语句,记录规则的基本思想是:预先计算经常要用或计算开销较大的表达式,并将其结果保存为一组新的时间序列。以上面提到的 http_server_requests_seconds_count 这个指标为例,优化前的一个监控图表的查询语句如下:
sum(rate(http_server_requests_seconds_count{application="$application", cluster=~"$cluster", uri!~"/actuator/.*|/\*.*|root|/|/health/check"}[1m])) by (uri)
从查询语句可以看出,该监控图表依赖于 application、cluster 和 uri 这三个标签的聚合数据,因此可以创建如下的记录规则(记录规则的详细创建方式可以参考 Prometheus 官方文档):
record: http_server_requests_seconds_count:rate:1m:acu
expr: sum(rate(http_server_requests_seconds_count{uri !~ "/actuator/.*|/\*.*|root|/|/health/check"}[1m])) by (application,cluster,uri)
记录规则创建后默认只包含记录规则创建时间之后的数据,并不包含创建之前的历史数据。Prometheus从 v2.27 版本开始支持通过命令行指令来手工回溯历史数据(对于 Prometheus v2.38及以下版本,需要在实例启动时开启--storage.tsdb.allow-overlapping-blocks 参数),通过 promtool tsdb create-blocks-from rules --help 可以了解该指令的使用,这里给出了一个该指令的样例:
promtool tsdb create-blocks-from rules
--start 1680348042
--end 1682421642
--url http://mypromserver.com:9090
rules.yaml
在实际场景中,如果有多个监控图表都用到了同一个监控指标,可以整体评估一下记录规则应该怎么创建。因为一个记录规则也是一组时间序列,在满足查询需求的前提下尽量避免创建过多的记录规则。
04
小结
当 Prometheus 指标基数过高时,就会出现监控图表加载很慢甚至加载失败。通过 Prometheus 提供的记录规则,我们可以对查询语句进行优化从而减少查询耗时。除了记录规则外,还有一些技巧可以优化查询性能,例如增加 Prometheus 指标采集间隔,删除不用的指标序列等。实际上,在监控指标设计阶段就应该对指标基数进行评估,必要时对标签取值进行取舍。例如,一个标签对应 HTTP 响应码,可以将它的取值定义为 1XX、2XX、3XX、4XX、5XX,相比详细的响应码可以大大降低指标基数。
推荐站内搜索:最好用的开发软件、免费开源系统、渗透测试工具云盘下载、最新渗透测试资料、最新黑客工具下载……
还没有评论,来说两句吧...