灯下哥谭 灯下哥谭
首页
关于
  • Hermes Agent 平台
  • Claude Code
  • OpenClaw
  • GPU 推理节点运维
  • DeepSeek Harness
  • MySQL 运维知识地图
  • Elasticsearch 运维知识地图
  • Redis 运维知识地图
  • TiDB 体系
  • DBA 常用 SQL 与命令
  • Nginx 运维知识地图
  • Prometheus 监控
  • Docker
  • Systemd
  • Iptables
  • Firewalld
  • Sshd
  • MySQL8 运维 SOP 手册
  • MySQL 实战 45 讲(读书笔记)
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

灯下哥谭

灯还亮着
首页
关于
  • Hermes Agent 平台
  • Claude Code
  • OpenClaw
  • GPU 推理节点运维
  • DeepSeek Harness
  • MySQL 运维知识地图
  • Elasticsearch 运维知识地图
  • Redis 运维知识地图
  • TiDB 体系
  • DBA 常用 SQL 与命令
  • Nginx 运维知识地图
  • Prometheus 监控
  • Docker
  • Systemd
  • Iptables
  • Firewalld
  • Sshd
  • MySQL8 运维 SOP 手册
  • MySQL 实战 45 讲(读书笔记)
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 工作笔记

  • 容器与编排

  • Nginx

  • 监控

    • prometheus监控介绍
    • PromQL介绍
      • 坑与边界
    • VictoriaMetrics 集群版:三组件架构与水平扩展机制解析
    • rclone常用命令参数详解(含 WebDAV 挂载实战)
  • 网络安全

  • 其他

  • Linux笔记
  • 监控
灯下哥谭
2023-06-27
目录

PromQL介绍原创

Prometheus Query Language (PromQL) 是一种功能强大的查询语言,用于在 Prometheus 中查询和分析时间序列数据。以下是一些常用的 PromQL 查询示例,帮助你在实际监控和分析中使用。

版本说明

本文写于 2023-06,2026-08 复核。
文中所有函数(rate / increase / avg_over_time / topk / delta)与聚合语法自 Prometheus 2.x 起未变,在 3.x 上同样适用。
指标名以 node_exporter 1.x 为准;跨大版本升级 exporter 时请用 curl localhost:9100/metrics | grep <指标名> 确认指标仍然存在。

# 基本查询

  1. 简单查询: 查询某个指标的当前值。

    node_cpu_seconds_total
    
    1
  2. 带条件的查询: 查询某个指标在特定条件下的当前值。

    node_cpu_seconds_total{mode="idle"}
    
    1

# 聚合操作

聚合函数默认会把所有匹配到的时间序列压成一条,这几乎不是你想要的——一个 200 台机器的集群,avg(node_memory_MemAvailable_bytes) 得到的是「全集群平均可用内存」,某台机器快 OOM 了这个数字也看不出来。实际使用时几乎总要带 by (instance),把聚合限制在单机维度内:

  1. 按实例求平均值:

    avg by (instance) (node_memory_MemAvailable_bytes)
    
    1
  2. 按实例求和(多网卡、多磁盘这类单机内有多条序列的指标才有意义):

    sum by (instance) (node_network_receive_bytes_total)
    
    1
  3. 最大值 / 最小值:

    max by (instance) (node_memory_MemAvailable_bytes)
    min by (instance) (node_memory_MemAvailable_bytes)
    
    1
    2

    不带 by 的 max(...) / min(...) 只在你确实想问「全集群最极端的那个值是多少」时才用,且这种写法丢失了 instance 标签——你会知道最小值是 300MB,但不知道是哪台机器。要同时拿到值和机器名,用 bottomk(1, node_memory_MemAvailable_bytes)。

# 计算速率

  1. 计算速率: 计算某个指标在一段时间内的变化速率。
    rate(node_cpu_seconds_total{mode="idle"}[5m])
    
    1

# 分组和子查询

  1. 按标签分组: 计算某个指标在不同标签维度上的总和。

    sum(rate(node_cpu_seconds_total[5m])) by (instance)
    
    1
  2. 分组并求平均值: 按某个标签分组并计算平均值。

    avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) by (instance)
    
    1

    别把 `avg` 直接套在多 mode 的 CPU 指标上

    上面这条特意加了 mode="idle"。node_cpu_seconds_total 同时带 cpu 和 mode 两个维度,写成 avg(rate(node_cpu_seconds_total[5m])) by (instance) 是把 8 个 mode 的速率一起求平均,得到的数值没有物理含义,不能当 CPU 使用率用(会比真实值小若干倍)。限定单个 mode 后,avg 跨的才是 CPU 核,语义才成立。完整推导见 Prometheus 监控介绍。

# 比率和百分比

  1. 计算CPU使用率: 计算 CPU 使用率(非空闲时间占比)。

    100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
    
    1
  2. 内存使用百分比: 计算内存使用百分比。

    (node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes * 100
    
    1

# 结合时间范围

  1. 查询过去5分钟的平均值: 计算过去5分钟某个指标的平均值。

    avg_over_time(node_load1[5m])
    
    1
  2. 查询特定时间点的值: 查询某个指标在特定时间点的值。

    node_load1 @ 1622476800
    
    1

# 常用的Prometheus报警规则

  1. CPU使用率报警: 当某个实例的CPU使用率超过80%时触发报警。

    100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80
    
    1
  2. 内存使用率报警: 当某个实例的内存使用率超过90%时触发报警。

    (node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes * 100 > 90
    
    1
  3. 磁盘使用率报警: 当某个实例的根目录磁盘使用率超过90%时触发报警。

    (
      node_filesystem_size_bytes{mountpoint="/", fstype!~"tmpfs|overlay|squashfs"}
      - node_filesystem_avail_bytes{mountpoint="/", fstype!~"tmpfs|overlay|squashfs"}
    )
    / node_filesystem_size_bytes{mountpoint="/", fstype!~"tmpfs|overlay|squashfs"} * 100 > 90
    
    1
    2
    3
    4
    5

    必须用 avail 而不是 free:node_filesystem_free_bytes 是文件系统层面的空闲块总数,其中包含了 ext4 默认预留给 root 的 5%(mke2fs 的 -m 5);node_filesystem_avail_bytes 才是非特权进程实际能用的空间。用 free 计算会系统性低估使用率约 5 个百分点——普通业务进程已经写不进去并开始报 No space left on device 了,用 free 算出来的使用率可能还停在 95% 以下,告警根本不触发。这是磁盘告警最经典的漏报原因。

    fstype!~ 那一段是排除 tmpfs、容器 overlay 层这类伪文件系统,否则一台跑 Docker 的机器会刷出几十条无意义的告警。

# 高级查询

  1. 查询前N个值: 查询某个指标的前5个最大值。

    topk(5, node_load1)
    
    1
  2. 查询区间增量: 计算某个 counter 指标在过去一小时内增长了多少。

    increase(node_network_receive_bytes_total[1h])
    
    1

    increase 和 delta 不能混用:node_network_receive_bytes_total 名字里的 _total 后缀表明它是 counter(只增不减,进程重启时归零)。delta() 按官方定义只适用于 gauge,它做的是「区间末值 - 区间首值」的外推,遇到计数器重置会算出负数——网卡计数器溢出或 node_exporter 重启,这个表达式就会给出一个荒谬的负增量。increase()(以及 rate())内部有 counter reset 检测,会自动把重置那一段补偿回来。

    判断法则很简单:指标名以 _total / _count / _sum 结尾的用 rate / increase,其余(内存、温度、队列长度这类可增可减的)才用 delta / deriv。

# 坑与边界

1. 区间向量的时长至少要覆盖 4 个采样点。 rate(x[5m]) 在 scrape_interval: 15s 下有 20 个点,很充裕;但如果某个 job 的抓取间隔是 2 分钟,[5m] 只有 2–3 个点,Prometheus 可能直接返回空值。经验法则是区间时长 ≥ 4 × scrape_interval,告警规则里尤其要注意——一条永远返回空的告警规则不会报错,它只是永远不触发。

2. rate 与 irate 不能凭感觉选。 rate 是整个区间的平均速率,曲线平滑,适合告警和趋势图;irate 只取区间内最后两个点,对尖刺极其敏感,适合排障时看瞬时抖动。告警规则里不要用 irate——它会因为单次采样抖动而反复触发和恢复。

3. 聚合会丢标签,且丢得静默。 sum(rate(http_requests_total[5m])) 把所有 method、status、instance 揉成一个数,不会有任何警告。写完聚合表达式后,先在 Graph 页面切到 Table 视图看一眼返回了几条序列、带哪些标签,再决定要不要加 by / without。

4. 告警表达式里的 > 90 是瞬时判断,必须配 for。 PromQL 表达式本身只回答「此刻是否超阈值」。真正的告警规则要在 YAML 里写 for: 5m,表示持续 5 分钟超阈值才发。缺了 for,一次采样抖动就会发一封告警邮件。

5. @ 修饰符(第 13 条)需要 Prometheus 2.25+,且默认关闭。 早期版本需要启动时加 --enable-feature=promql-at-modifier 才能用,2.29 之后才成为默认可用。在老集群上直接写 @ 会报解析错误。

#可观测性
上次更新: 9/11/2026

← prometheus监控介绍 VictoriaMetrics 集群版:三组件架构与水平扩展机制解析→

最近更新
01
DeepSeek Harness 实战 06|学习笔记:插件、工具、技能不在同一个维度上 原创
09-11
02
DeepSeek Harness 实战 05|让两个编码 Agent 共用一份长期记忆 原创
09-09
03
DeepSeek Harness 实战 04|学习笔记:从「已知限制」里读出三处设计张力 原创
09-08
更多文章>
Theme by Vdoing
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式