4、Prometheus基础入门:Prometheus架构、核心概念与PromQL基础语法

大家好,我是你们的运维老手。今天咱们聊聊Prometheus,这个在云原生监控领域几乎成了标配的系统。说实话,我刚开始接触它的时候,也觉得概念有点多,但用顺手了之后,你会发现它设计得非常巧妙。

这一节,我会从架构、核心概念到查询语法,带你一步步把Prometheus的底裤看穿。嗯,准备好了吗?

4.1 Prometheus架构:Pull模型与TSDB

先说说它的架构。Prometheus最核心的设计就是Pull模型。什么意思呢?就是Prometheus Server主动去各个目标(比如你的vLLM服务)拉取指标数据,而不是等目标把数据推过来。

为什么用Pull而不是Push?

我个人觉得,Pull模型最大的好处是可控性。你可以统一控制采集频率、超时时间,甚至可以在Server端做服务发现。如果某个目标挂了,你立刻就能从拉取失败中感知到。我曾经在一个项目中,因为网络分区导致Push模式的数据全丢了,从那以后,我对Pull模型就情有独钟。

下面这张图,是我手绘的Prometheus核心架构,你看一眼就明白了:

Prometheus 核心架构(Pull模型) Prometheus Server Pull 指标数据 存储到 TSDB TSDB(时序数据库) 目标1:vLLM 服务 /metrics 端点暴露指标 目标2:Node Exporter 主机指标(CPU/内存) 目标3:其他服务 自定义指标 HTTP Pull (主动拉取) Alertmanager 告警通知 Grafana 可视化仪表盘

你看,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"}

这里的 modelstatus 就是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 聚合操作

聚合操作可以让你把多个时间序列合并成一个。常用的有 sumavgmaxmincount 等。

比如,我想看所有模型的总请求数:

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监控指标的基石。你把这些搞懂了,后面配置采集规则和告警规则就会轻松很多。


专注资料整理