关于SysDig中PromQL两种CPU使用率查询的疑问
背景
SysDig支持$__interval和$__interval_sec两个特殊变量,它们会根据当前仪表盘的时间范围自动设置为对应比例的时间间隔,作为相邻数据点的显示间隔。例如:
- 当显示时间范围为1分钟时,
$__interval_sec可能等于底层数据的采样间隔(如10秒); - 当显示时间范围扩大到6小时时,
$__interval_sec会被提升至60秒。
我的需求是展示collectd CPU插件上报的CPU使用率百分比(用户时间与系统时间之和),最初编写的PromQL查询如下:
sum(collectd_cpu_percent{cpu=~"system|user"}) by (....) # (1)
但在官方示例中,同类场景会结合$__interval变量和时间聚合函数来实现:
sum(avg_over_time(collectd_cpu_percent{cpu=~"system|user"}[$__interval])) by (....) # (2)
经过实验发现,即使$__interval_sec超过底层数据的采样间隔,两个查询在仪表盘上显示的数据点完全一致。我理解查询(2)的逻辑是:对每个$__interval间隔内的采样数据取平均值,再求和得到显示数据点;但如果查询(1)仅取显示时间点的采样数据,在数据有波动时应该和(2)产生差异,实际却没有,因此怀疑查询(1)底层也做了聚合处理。
问题
- 查询(1)和(2)之间有什么差异?
- 为什么两个查询在SysDig仪表盘面板中显示的数据点完全一致?
- 若查询(1)底层也会对采样数据进行聚合,使用的是哪种聚合函数?
解答
1. 查询(1)与(2)的核心差异
- 聚合逻辑顺序:查询(1)是先对同一时间点的
system和user类型CPU使用率求和,再由仪表盘处理数据点的展示聚合;查询(2)是先对每个$__interval时间窗口内的单类型CPU使用率取平均,再对窗口内的两类平均值求和,最后按窗口输出数据点。 - 聚合触发方式:查询(1)的聚合(若存在)是SysDig仪表盘的后端隐式逻辑自动触发的;查询(2)的聚合是PromQL表达式显式指定的,由PromQL引擎执行。
- 自定义能力:查询(2)可以手动替换时间聚合函数(比如换成
max_over_time或sum_over_time),而查询(1)的聚合逻辑完全由SysDig的仪表盘规则决定,无法自定义。
2. 数据点一致的原因
SysDig仪表盘在渲染数据时,会根据当前面板的时间范围和$__interval参数,自动对未指定时间聚合的查询(如查询(1))执行隐式降采样聚合:当需要展示的时间间隔($__interval)大于底层数据的采样间隔时,SysDig会自动将多个采样点合并为一个显示点,以匹配仪表盘的分辨率。而这种隐式聚合默认使用的逻辑,和你显式用avg_over_time再求和的逻辑完全匹配,因此最终显示的数据点完全一致。
3. 查询(1)底层使用的聚合函数
从你的实验结果(数据波动时与avg_over_time结果一致)可以推断,SysDig对查询(1)的隐式聚合使用的是**平均值(average)**函数。这是监控仪表盘降采样时的通用默认行为——用平均值平衡数据的整体趋势和局部波动,避免丢失核心特征。
内容的提问来源于stack exchange,提问作者Andreas Maier

