4、Prometheus基础入门:Prometheus架构、核心概念与PromQL基础语法
大家好,我是你们的运维老手。今天咱们聊聊Prometheus,这个在云原生监控领域几乎成了标配的系统。说实话,我刚开始接触它的时候,也觉得概念有点多,但用顺手了之后,你会发现它设计得非常巧妙。
这一节,我会从架构、核心概念到查询语法,带你一步步把Prometheus的底裤看穿。嗯,准备好了吗?
4.1 Prometheus架构:Pull模型与TSDB
先说说它的架构。Prometheus最核心的设计就是Pull模型。什么意思呢?就是Prometheus Server主动去各个目标(比如你的vLLM服务)拉取指标数据,而不是等目标把数据推过来。
为什么用Pull而不是Push?
我个人觉得,Pull模型最大的好处是可控性。你可以统一控制采集频率、超时时间,甚至可以在Server端做服务发现。如果某个目标挂了,你立刻就能从拉取失败中感知到。我曾经在一个项目中,因为网络分区导致Push模式的数据全丢了,从那以后,我对Pull模型就情有独钟。
下面这张图,是我手绘的Prometheus核心架构,你看一眼就明白了:
你看,Prometheus Server 主动去拉取各个目标暴露的指标,然后存到自己的TSDB(时序数据库)里。TSDB是专门为时间序列数据优化的存储引擎,写入快、压缩率高。我见过不少新手问:“为什么不用MySQL存监控数据?” 你想想看,每秒几万个时间点写入,MySQL早就跪了。TSDB就是干这个的。
小提示: 在vLLM中,你只需要在启动时加上 --metrics-endpoint 参数,就会在 /metrics 路径暴露Prometheus格式的指标。然后你在Prometheus配置文件里加上这个target就行了。
4.2 核心概念:Metric、Label、Sample
这三个概念,是理解Prometheus的基石。说白了,它们就是监控数据的“三要素”。
4.2.1 Metric(指标名)
Metric就是指标的名字,比如 vllm:request_count_total。它描述了你监控的是什么。我个人习惯用命名空间加下划线的方式,比如 vllm_gpu_memory_used_bytes,一看就知道是vLLM的GPU内存使用量。
4.2.2 Label(标签)
Label是键值对,用来给指标打上不同的维度。比如:
vllm_request_count_total{model="llama-70b", status="success"}
这里的 model 和 status 就是Label。你可以通过Label来筛选、聚合数据。我曾经踩过一个坑:Label的值如果变化太频繁(比如把用户ID当Label),会导致TSDB的索引爆炸。记住,Label的基数(唯一值数量)不要太高,一般建议控制在几千以内。
4.2.3 Sample(样本)
Sample就是实际的数据点了。它包含三部分:
- 时间戳:精确到毫秒
- 值:float64浮点数
- 指标名+Label:标识这个数据属于谁
举个例子,一个完整的Sample长这样:
vllm_request_latency_seconds{model="llama-70b", quantize="awq"} 0.234 1696000000000
最后那个大数字就是时间戳。嗯,这里要注意,Prometheus的Sample值只能是数字,不能是字符串。如果你想记录一些状态信息,得用Info类型的指标。
避坑指南: 我曾经见过有人把错误码(比如"404")直接当Label值,结果因为Label值包含特殊字符,导致PromQL查询时报错。Label值最好只用字母、数字和下划线。
4.3 PromQL基础语法
PromQL是Prometheus的查询语言,说白了就是用来从TSDB里捞数据的。刚开始学的时候,你可能会觉得它有点像函数式编程,但用多了就会发现它很强大。
4.3.1 即时查询与范围查询
这是最基础的两个概念:
- 即时查询:查某个时间点的数据。比如
vllm_request_count_total返回当前最新的值。 - 范围查询:查一段时间内的数据。比如
vllm_request_count_total[5m]返回过去5分钟的所有样本。
我个人习惯在排查问题时先用即时查询看当前状态,再用范围查询看趋势。
4.3.2 选择器
选择器就是用来筛选数据的。常用的有:
- 精确匹配:
vllm_request_count_total{model="llama-70b"} - 正则匹配:
vllm_request_count_total{model=~"llama-.*"} - 排除匹配:
vllm_request_count_total{model!="llama-70b"}
举个例子,我想看所有非llama模型的请求量:
vllm_request_count_total{model!~"llama-.*"}
4.3.3 聚合操作
聚合操作可以让你把多个时间序列合并成一个。常用的有 sum、avg、max、min、count 等。
比如,我想看所有模型的总请求数:
sum(vllm_request_count_total)
如果想按模型分组求和:
sum by (model) (vllm_request_count_total)
你想想看,这个查询在Grafana面板上画出来,就是每个模型一条线,非常直观。
4.3.4 常用函数
PromQL内置了很多函数,我挑几个最常用的:
| 函数 | 作用 | 示例 |
|---|---|---|
rate() |
计算每秒增长率(用于Counter类型) | rate(vllm_request_count_total[5m]) |
irate() |
计算瞬时增长率(更敏感) | irate(vllm_request_count_total[5m]) |
increase() |
计算一段时间内的增量 | increase(vllm_request_count_total[1h]) |
avg_over_time() |
计算一段时间内的平均值 | avg_over_time(vllm_gpu_memory_used_bytes[10m]) |
重点提醒: 对于Counter类型的指标(比如请求总数),一定要用 rate() 或 increase() 函数,不要直接查原始值。因为Counter只会增加,直接查原始值你看不出趋势。我刚开始学的时候也犯过这个错,查出来一条一直往上的直线,还以为系统出问题了。
4.3.5 一个完整的查询示例
假设我们想监控vLLM服务的每秒请求数,并且按模型和状态分组:
rate(vllm_request_count_total[5m])
如果想看成功率(成功请求占总请求的比例):
sum(rate(vllm_request_count_total{status="success"}[5m]))
/
sum(rate(vllm_request_count_total[5m]))
这个查询会返回一个0到1之间的小数,乘以100就是百分比。我在做SLA监控时经常用这个。
个人经验: 刚开始写PromQL时,建议先在Prometheus的Web UI(默认在 http://localhost:9090)的Graph页面里试。那里有自动补全,还能实时看到结果曲线,比直接写配置文件方便多了。
好了,这一节的内容就到这里。Prometheus的基础架构、核心概念和PromQL语法,是后续我们接入vLLM监控指标的基石。你把这些搞懂了,后面配置采集规则和告警规则就会轻松很多。