17.5.5 常见查询模式与性能优化

常见查询模式与性能优化#

在运维场景中,PromQL常见查询集中在资源利用、服务可用性、延迟与吞吐、容量趋势、告警诊断等方面。编写查询时应围绕“明确时间范围、控制维度基数、选择合适函数、避免高开销算子”四个原则,保证结果准确且性能可控。

原理草图:查询与聚合路径#

文章图片

1)资源利用与容量趋势(含示例与解释)#

CPU使用率

sum by (instance) (rate(node_cpu_seconds_total{mode!="idle"}[5m]))
  • rate:计算5分钟内增量速率
  • mode!="idle":排除空闲时间

按核数归一化

sum by (instance) (rate(node_cpu_seconds_total{mode!="idle"}[5m]))
/ count by (instance) (node_cpu_seconds_total{mode="idle"})
  • count:统计CPU核数

内存使用率

1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)
  • MemAvailable:比MemFree更贴近可用内存

磁盘使用率与趋势

1 - (node_filesystem_avail_bytes{fstype!~"tmpfs|overlay"} 
     / node_filesystem_size_bytes{fstype!~"tmpfs|overlay"})
predict_linear(node_filesystem_avail_bytes[6h], 24*3600)
  • predict_linear:预测未来24小时可用空间趋势

2)服务可用性与SLA(含示例与解释)#

探测成功率

avg_over_time(probe_success[5m])

错误率

sum(rate(http_requests_total{status=~"5.."}[5m]))
/ sum(rate(http_requests_total[5m]))

SLO误差预算消耗

1 - (
  sum(rate(http_requests_total{status!~"5.."}[30d]))
  / sum(rate(http_requests_total[30d]))
)

3)延迟与吞吐(含示例与解释)#

请求吞吐

sum(rate(http_requests_total[1m]))

P95 / P99 延迟

histogram_quantile(0.95, sum by (le) (rate(http_request_duration_seconds_bucket[5m])))
histogram_quantile(0.99, sum by (le) (rate(http_request_duration_seconds_bucket[5m])))

4)K8s与容器常用模式(含示例与解释)#

Pod CPU使用

sum by (namespace,pod) (rate(container_cpu_usage_seconds_total{container!="",image!=""}[5m]))

Pod内存使用

sum by (namespace,pod) (container_memory_working_set_bytes{container!="",image!=""})

节点资源压力

node_load1 / count by (instance) (node_cpu_seconds_total{mode="idle"})

性能优化与查询实践#

1)控制时间范围与步长#

  • 实时分析:[1m]/[5m]
  • 趋势分析:[6h]/[24h]配合子查询
  • Grafana建议:step ≈ range/250~500

子查询示例

avg_over_time((sum by (job) (rate(http_requests_total[1m])))[1h:5m])

2)减少高基数标签#

  • by分组只保留必要维度
  • 高基数字段如podcontainerpath避免直接聚合输出

3)选择低成本函数与算子#

  • 趋势用rate,短时波动用irate
  • 避免大范围topkcount_valueslabel_replace

4)使用录制规则(Recording Rules)#

rules文件示例

# /etc/prometheus/rules/http.rules.yml
groups:
- name: http.rules
  rules:
  - record: job:request_rate:5m
    expr: sum(rate(http_requests_total[5m])) by (job)

加载配置并重载

promtool check rules /etc/prometheus/rules/http.rules.yml
curl -X POST http://127.0.0.1:9090/-/reload
  • promtool check rules:语法检查
  • /-/reload:热加载配置

5)避免无意义的全局扫描#

  • 总是加过滤条件:
sum(rate(node_cpu_seconds_total{job="node-exporter"}[5m]))

安装与验证(PromQL调试与规则检查)#

安装promtool(随Prometheus发行包)

# 以二进制包为例
tar -zxvf prometheus-2.49.1.linux-amd64.tar.gz
cd prometheus-2.49.1.linux-amd64
./promtool --version

本地验证PromQL表达式

./promtool query instant http://127.0.0.1:9090 \
  'sum(rate(http_requests_total[1m]))'

典型性能问题与排错步骤#

问题1:查询慢
1. 缩短时间范围:从[24h]降到[1h]
2. 过滤标签:加入job/instance/namespace
3. 使用录制规则替代复杂查询

问题2:结果不稳定
1. 将irate改为rate
2. 检查采样间隔与目标抓取状态:

curl -s http://127.0.0.1:9090/api/v1/targets | jq '.data.activeTargets[] | {job: .labels.job, health: .health}'

问题3:Prometheus负载高
1. 限制高基数指标(在Exporter侧清洗)
2. 拆分Prometheus实例
3. 使用远程存储与查询层


练习题(含目标与提示)#

  1. 计算某实例过去1小时CPU平均使用率
    提示:avg_over_time + rate
  2. 统计所有Pod的P99延迟
    提示:histogram_quantile + sum by (le)
  3. 为HTTP请求速率编写录制规则并验证加载
    提示:使用promtool check rules/-/reload