我们最近听说一个客户,一个Prometheus的高级用户,正在为其指标处理18,000条单独的规则,因为其设置涉及为每个生成的指标创建一个单独的规则组。肯定有一个更好、更有效的方法来处理这种规模的指标?
事实上,我们确实想出了一个解决方案,这篇博文将告诉你,你也可能从中受益。
我们需要做的是
这个组织正在为每个生成的指标创建一个单独的规则组。
比如说:
groups:
- name: slo_metric
expr: count(api_response_latency_ms{labelone="xyz", labeltwo="abc"} > 100)
labels:
reference_label: xyzabc123
上面的记录规则的原因是,客户想把reference_label添加到公制的汇总版本中。参考标签对应的是每个系列上已经存在的两个预先存在的标签。目前的问题是如何在不改变基础系列的情况下,用所需的相关参考标签创建新的聚合系列?
在想出一个替代方案时,我们考虑到了以下几点。
信息度量
普罗米修斯中的信息度量是一种不对测量进行编码的度量,而是用来对高分类标签值进行编码。一个信息度量的例子是node_uname_info:
node_uname_info{cluster="dev-us-central-0", domainname="(none)", instance="localhost", job="default/node-exporter", machine="x86_64", namespace="default", nodename="dev-host-1", release="4.19.150+", sysname="Linux", version="#1 SMP Tue Nov 24 07:54:23 PST 2020"} 1
上述度量是由节点导出器暴露出来的,是一个测量值总是设置为1的度量。尽管这个度量值本身并不有用,但它与其他度量值一起使用会很有用。例如,如果你想通过操作系统的发布来确定CPU的空闲时间,你就可以使用这个查询:
sum by (release) (rate(node_cpu_seconds_total{mode="idle"}[5m]) * on (instance) group_left(release) node_uname_info)
你可能有的下一个问题是,你如何能够轻松地创建一个具有正确标签值的信息度量,并迅速将其刮入Prometheus。你总是可以用你想要的指标来创建一个应用程序,但还有一个更简单的方法。你可以利用textfile_collector的优势。
文本文件导出器
普罗米修斯节点导出器和Grafana代理都支持文本文件收集器。这允许代理解析和收集一个包含Prometheus论述格式的指标的文本文件。这个功能对于快速生成包含对PromQL查询有用的元数据的静态指标很重要。
利用上述功能,你可以创建包含独特标签集的信息度量,可以在PromQL连接查询中与其他度量一起使用。你所需要做的就是创建一个包含你所需要的信息度量的文件,并将它们暴露给Prometheus。你可以用手或脚本来做这件事。
关于一些可以用来生成包含由文本文件收集器收集的指标的文件的脚本例子,请参见Prometheus社区脚本库。
PromQL中的连接
PromQL支持将两个指标连接起来的能力。你可以从一个度量标准中附加一个标签集,并在查询时将其附加到另一个度量标准。这在Prometheus规则评估中很有用,因为它可以让你通过附加另一个信息指标的标签来为一个系列生成一个新的指标。
关于连接运算符的更多信息,请参阅Prometheus查询运算符的文档,并查看这些博客文章。
将所有的东西结合起来
你可以重新利用生成18,000个规则组的工具,转而生成一个包含指标sli_info的普罗米修斯指标文件。这个指标将包含海豹参考和海豹标识(sealID)、检查标识(checkID),以及任何其他它适当映射到的标签。
接下来,使用Grafana代理内置的文本文件收集器收集生成的度量,并将其写入Cortex。
为每个指标运行一条规则,使用PromQL连接将适当的参考标签注入生成的系列中。
例如,基于上述规则组:
groups:
- name: slo_metric
expr: count(api_response_latency{labelone="xyz", labeltwo="abc"} > 100)
labels:
reference_label: xyzabc
你将创建以下信息度量文件:
sli_info{labelone="xyz", labeltwo="abc", reference_label="xyzabz"} 1
这个文件将被Grafana Agent收集。然后,以下规则组可以在Cortex中使用:
groups:
- name: slo_metric
expr: count by (reference_label) ((api_response_latency * on (labelone,labeltwo) group_left(reference_label) sli_info > 100)
这将对具有这些标签名称和相关映射的每个指标起作用。
瞧!你得到的结果和现有的一样。你得到了与现有规则组相同的结果,而没有18000个单独的规则。