2、PromQL 基础回顾:瞬时向量与区间向量、标签匹配器、基础聚合操作
在深入多租户隔离实践之前,必须牢固掌握 PromQL 的三大核心基础:数据类型(瞬时向量与区间向量)、标签筛选机制(标签匹配器)以及基础聚合操作(sum、avg、min、max)。这些概念是构建租户级查询隔离的基石。
2.1 瞬时向量与区间向量
PromQL 查询返回的数据主要分为两种向量类型,理解它们的区别是正确使用聚合函数的前提。
| 向量类型 | 英文名称 | 含义 | 典型语法 | 返回结果 |
|---|---|---|---|---|
| 瞬时向量 | Instant Vector | 每个时间序列在当前时刻的一个最新样本值 | http_requests_total |
一组键值对,每个时间序列对应一个值 |
| 区间向量 | Range Vector | 每个时间序列在过去一段时间范围内的一组样本值 | http_requests_total[5m] |
一组键值对,每个时间序列对应一个样本数组 |
关键区别: 瞬时向量用于点查和聚合;区间向量用于趋势分析和速率计算(如 rate()、increase())。聚合操作(sum/avg/min/max)通常作用于瞬时向量。
2.2 标签匹配器(Label Matchers)
标签匹配器是 PromQL 实现多租户隔离的核心武器。通过在查询中精确匹配租户标签,可以确保一个租户的查询不会泄漏到其他租户的数据中。PromQL 支持四种匹配器:
| 匹配器 | 含义 | 示例 | 说明 |
|---|---|---|---|
= |
完全相等 | tenant_id="acme" |
精确匹配标签值,最常用 |
!= |
不等于 | tenant_id!="acme" |
排除特定租户,用于黑名单场景 |
=~ |
正则匹配 | tenant_id=~"acme|beta" |
匹配多个租户或模糊匹配 |
!~ |
正则排除 | tenant_id!~"test-.*" |
排除符合正则的租户 |
最佳实践: 在多租户场景中,建议将
tenant_id 作为强制标签。所有查询入口(如 Grafana 变量、告警规则)都应自动注入 tenant_id="xxx" 匹配器,从源头隔离数据。
2.3 基础聚合操作(sum、avg、min、max)
聚合操作将多个时间序列合并为一个或一组结果。在多租户场景中,聚合通常与 by 或 without 子句配合使用,以保留租户维度。
| 聚合函数 | 作用 | 典型场景 |
|---|---|---|
sum |
求和 | 计算租户总请求量、总资源消耗 |
avg |
平均值 | 计算租户平均响应时间、平均 CPU 使用率 |
min |
最小值 | 找出租户最低可用率、最低水位 |
max |
最大值 | 找出租户峰值流量、最高延迟 |
租户隔离聚合示例:
该查询先通过标签匹配器筛选出 acme 和 beta 两个租户的数据,然后按 tenant_id 分组求和,返回每个租户的总请求量。
sum by (tenant_id) (http_requests_total{tenant_id=~"acme|beta"})该查询先通过标签匹配器筛选出 acme 和 beta 两个租户的数据,然后按 tenant_id 分组求和,返回每个租户的总请求量。
2.4 聚合与标签保留
在多租户场景中,by 和 without 子句决定了哪些标签在聚合后保留:
by (tenant_id):显式指定保留tenant_id标签,其他标签被丢弃。这是多租户隔离的推荐方式。without (instance):排除instance标签,保留其余所有标签(包括tenant_id)。适用于需要保留多个维度的场景。
常见陷阱: 如果聚合时忘记使用
by 或 without,PromQL 会默认聚合所有维度,导致租户数据被合并,失去隔离性。例如:sum(http_requests_total) 会返回所有租户的总和,这在多租户场景中通常是错误的。