跳转至

第三章:PromQL 查询语言

什么是 PromQL?

PromQL(Prometheus Query Language)是 Prometheus 的查询语言,用于查询和聚合时间序列数据。

基本语法

即时向量查询

# 查询指标
http_requests_total

# 按标签过滤
http_requests_total{method="GET"}
http_requests_total{method!="POST"}
http_requests_total{status=~"2.."}
http_requests_total{status!~"5.."}

范围向量查询

# 查询过去 5 分钟的数据
http_requests_total[5m]

# 查询过去 1 小时的数据
http_requests_total[1h]

# 时间单位
s - 
m - 分钟
h - 小时
d - 
w - 
y - 

偏移量

# 查询 5 分钟前的数据
http_requests_total offset 5m

# 查询昨天的数据
http_requests_total[1d] offset 1d

数据类型

即时向量(Instant Vector)

一组时间序列,每个序列有一个采样值:

http_requests_total

范围向量(Range Vector)

一组时间序列,每个序列有多个采样值:

http_requests_total[5m]

标量(Scalar)

一个简单的数字值:

123
3.14

字符串(String)

一个字符串值:

"hello"
'world'

操作符

算术操作符

# 加法
node_memory_total_bytes + 1024

# 减法
node_memory_total_bytes - node_memory_free_bytes

# 乘法
node_memory_usage_bytes * 100

# 除法
node_memory_usage_bytes / node_memory_total_bytes

# 取模
node_memory_usage_bytes % 1024

# 幂运算
node_memory_usage_bytes ^ 2

比较操作符

# 等于
http_requests_total == 100

# 不等于
http_requests_total != 100

# 大于
node_memory_usage_bytes > 1000000000

# 小于
node_memory_usage_bytes < 1000000000

# 大于等于
node_memory_usage_bytes >= 1000000000

# 小于等于
node_memory_usage_bytes <= 1000000000

逻辑操作符

# 与
http_requests_total > 100 and http_requests_total < 1000

# 或
http_requests_total > 1000 or http_requests_total < 10

# 除非
http_requests_total unless http_requests_total{status="200"}

向量匹配

# 忽略标签匹配
sum(http_requests_total) / ignoring(instance) sum(http_requests_total)

# 按标签匹配
sum(http_requests_total) by (method) / on(method) sum(http_requests_total)

# 分组匹配
sum(http_requests_total) by (method) / group_left sum(http_requests_total)

聚合操作

基本聚合

# 总和
sum(http_requests_total)
sum by (method) (http_requests_total)
sum without (instance) (http_requests_total)

# 平均值
avg(node_memory_usage_bytes)
avg by (instance) (node_memory_usage_bytes)

# 最小值
min(node_memory_usage_bytes)

# 最大值
max(node_memory_usage_bytes)

# 计数
count(http_requests_total)
count by (status) (http_requests_total)

# 值计数
count_values("status", http_requests_total)

分位数

# 计算分位数
quantile(0.5, http_request_duration_seconds)
quantile(0.9, http_request_duration_seconds)
quantile(0.99, http_request_duration_seconds)

# 按标签分组计算分位数
quantile by (method) (0.95, http_request_duration_seconds)

标准差和方差

# 标准差
stddev(node_memory_usage_bytes)

# 方差
stdvar(node_memory_usage_bytes)

TopK 和 BottomK

# 前 10 个最大值
topk(10, http_requests_total)

# 前 10 个最小值
bottomk(10, http_requests_total)

函数

数学函数

# 绝对值
abs(node_memory_usage_bytes)

# 向上取整
ceil(node_memory_usage_bytes)

# 向下取整
floor(node_memory_usage_bytes)

# 四舍五入
round(node_memory_usage_bytes, 100)

# 平方根
sqrt(node_memory_usage_bytes)

# 对数
log(node_memory_usage_bytes)
log2(node_memory_usage_bytes)
log10(node_memory_usage_bytes)

# 指数
exp(node_memory_usage_bytes)

时间函数

# 当前时间
time()

# 指标过期时间
time() - timestamp(http_requests_total)

# 小时
hour()

# 分钟
minute()

# 月份
month()

# 年份
year()

# 星期
day_of_week()

# 日期
day_of_month()

变化率函数

# 计算速率(适用于 Counter)
rate(http_requests_total[5m])

# 计算增量
increase(http_requests_total[1h])

# 计算平均速率(适用于 Gauge)
irate(http_requests_total[5m])

# 计算变化量
delta(node_memory_usage_bytes[5m])

示例:请求速率

# 每秒请求数
rate(http_requests_total[5m])

# 每分钟请求数
rate(http_requests_total[5m]) * 60

# 每小时请求数
increase(http_requests_total[1h])

统计函数

# 变化次数
changes(node_memory_usage_bytes[1h])

# 值数量
count_over_time(http_requests_total[5m])

# 总和
sum_over_time(node_memory_usage_bytes[1h])

# 平均值
avg_over_time(node_memory_usage_bytes[1h])

# 最小值
min_over_time(node_memory_usage_bytes[1h])

# 最大值
max_over_time(node_memory_usage_bytes[1h])

# 标准差
stddev_over_time(node_memory_usage_bytes[1h])

# 分位数
quantile_over_time(0.95, node_memory_usage_bytes[1h])

标签操作函数

# 添加标签
label_replace(http_requests_total, "new_label", "value", "old_label", "regex")

# 连接标签
label_join(http_requests_total, "new_label", "-", "label1", "label2")

示例:标签操作

# 从 instance 提取主机名
label_replace(up, "hostname", "$1", "instance", "(.*):.*")

# 组合多个标签
label_join(http_requests_total, "combined", "-", "method", "status")

直方图函数

# 计算分位数
histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m]))

# 按 label 分组计算分位数
histogram_quantile(0.95, sum by (le, method) (rate(http_request_duration_seconds_bucket[5m])))

# 计算平均值
rate(http_request_duration_seconds_sum[5m]) / rate(http_request_duration_seconds_count[5m])

常用查询示例

CPU 使用率

# CPU 使用率
100 - (avg by (instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)

# 按模式分组
avg by (mode) (irate(node_cpu_seconds_total[5m])) * 100

内存使用率

# 内存使用率
(1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100

# 已使用内存
node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes

# 缓存内存
node_memory_Cached_bytes + node_memory_Buffers_bytes

磁盘使用率

# 磁盘使用率
(1 - (node_filesystem_avail_bytes{fstype!~"tmpfs|overlay"} / node_filesystem_size_bytes{fstype!~"tmpfs|overlay"})) * 100

# 磁盘 IO
rate(node_disk_read_bytes_total[5m])
rate(node_disk_written_bytes_total[5m])

网络流量

# 网络接收速率
rate(node_network_receive_bytes_total[5m])

# 网络发送速率
rate(node_network_transmit_bytes_total[5m])

# 网络错误率
rate(node_network_receive_errs_total[5m]) + rate(node_network_transmit_errs_total[5m])

HTTP 请求

# 请求速率
sum(rate(http_requests_total[5m]))

# 按状态码分组
sum by (status) (rate(http_requests_total[5m]))

# 错误率
sum(rate(http_requests_total{status=~"5.."}[5m])) / sum(rate(http_requests_total[5m])) * 100

# 请求延迟 P95
histogram_quantile(0.95, sum by (le) (rate(http_request_duration_seconds_bucket[5m])))

应用可用性

# 服务可用性
avg(up) * 100

# 按服务分组
avg by (job) (up) * 100

子查询

# 过去 1 小时内,每 5 分钟的最大值
max_over_time(http_requests_total[1h:5m])

# 过去 30 分钟内,每 1 分钟的平均值
avg_over_time(rate(http_requests_total[5m])[30m:1m])

小结

本章学习了:

  • ✅ PromQL 基本语法
  • ✅ 数据类型
  • ✅ 操作符
  • ✅ 聚合操作
  • ✅ 内置函数
  • ✅ 常用查询示例

下一章

第四章:Exporter 数据采集 - 学习数据采集配置。