promql 的 ON() 查询能力
ON 级联查询说明
PromQL(Prometheus Query Language)是 Prometheus 监控系统使用的查询语言,用来从 Prometheus 数据库中检索时间序列数据。ON() 是 PromQL 中的一种操作符,它用于在执行向量匹配时指定哪些标签应该用来匹配两个向量。
在 PromQL 中,你可以使用不同的操作符来组合或对比两个时间序列向量,比如 +(加)、-(减)、*(乘)、/(除)等。当这些操作符用于两个向量之间时,Prometheus 需要一种方法来决定哪些时间序列应该配对进行计算。这就是 ON() 和 IGNORING() 操作符的作用。
ON() 操作符允许你指定在进行向量之间的操作时,哪些标签必须相匹配。只有当指定的标签完全匹配时,两个时间序列才会被配对。
例如,假设你有两个时间序列,一个是以实例为标签的机器的CPU使用率(cpu_usage),另一个是同样以实例为标签的机器的内存使用率(memory_usage)。如果你想要计算每个实例的CPU和内存使用率之和,你可以使用 ON() 操作符来确保只有标签 instance 相同的时间序列被配对:
cpu_usage + on(instance) memory_usage
这个查询将会返回一个新的时间序列向量,其中每个元素都是相同 instance 标签的 cpu_usage 和 memory_usage 的和。
如果没有使用 ON() 或 IGNORING(),Prometheus 默认会要求所有标签都必须匹配,除了那些在操作中出现的标签(也就是说,标签既不是操作数的一部分,也不是操作符的一部分)。这通常是不可取的,因为可能会导致没有任何时间序列相匹配,尤其是在存在额外的标签(如 job 或 region)时。
使用 ON() 操作符可以精确控制哪些标签用于匹配,从而使得查询更加灵活和精确。
如果两个指标 label 名称不一致,但是我想通过 ON 进行匹配,该怎么做?
如果你有两个指标(metrics)的标签名称不一致,但你想通过这些标签进行匹配,你可以使用 PromQL 的 label_replace 函数来临时重命名标签。这样,你就可以创建一个临时的标签,使得两个指标具有相同的标签名称,然后使用 ON() 来匹配这些标签。
label_replace 函数的一般形式如下:
label_replace(<vector>, "<new_label>", "<replacement>", "<src_label>", "<regex>")
<vector>: 要操作的时间序列向量。
<new_label>: 要创建或更新的标签的名称。
<replacement>: 替换 <src_label> 的值。
<src_label>: 要被替换或复制的现有标签的名称。
<regex>: 一个正则表达式,用于提取 <src_label> 的值中的一部分作为 <new_label> 的值。
举个例子,假设你有两个指标 metric1 和 metric2。metric1 有一个标签 label1,而 metric2 有一个标签 label2,你知道这两个标签在逻辑上是一致的,即 label1 的值应该与 label2 的值相对应。你可以这样使用 label_replace 来创建一个新的临时标签 temp_label,然后使用 ON() 进行匹配:
metric1 + on(temp_label) label_replace(metric2, "temp_label", "$1", "label2", "(.)")
在这个例子中,我们对 metric2 使用了 label_replace 函数,创建了一个新的标签 temp_label,它的值直接取自 label2(因为正则表达式 (.) 匹配了整个标签的值)。然后我们在两个指标之间进行加法操作,并通过 ON(temp_label) 保证只有当 metric1 的 label1 和 metric2 的 temp_label 相匹配时,才会进行计算。
注意,label_replace 是在查询执行时临时应用的,不会影响存储在 Prometheus 中的实际数据。