第四章:Prometheus监控体系:Metrics暴露、ServiceMonitor配置、Grafana看板设计

监控这件事,说白了就是给系统装个“心电图”。vLLM跑在K8s上,你不盯着点,出事了连怎么死的都不知道。我见过太多团队,模型推理延迟飙到10秒了还在那傻等,一问监控,啥也没有。嗯,今天咱们就把这套体系搭起来。

4.1 vLLM的Metrics暴露:从源码到端点

vLLM本身自带Prometheus指标,但很多人不知道。你启动服务时加个--metrics-port参数就行。我个人习惯用8080端口,跟推理端口分开,避免干扰。

# 启动命令示例
python -m vllm.entrypoints.openai.api_server \
    --model meta-llama/Llama-2-7b-chat-hf \
    --port 8000 \
    --metrics-port 8080

启动后,访问http://<pod-ip>:8080/metrics就能看到一堆指标。核心指标我列一下:

指标名 类型 含义
vllm:num_requests_running Gauge 当前正在处理的请求数
vllm:num_requests_waiting Gauge 排队等待的请求数
vllm:gpu_cache_usage_perc Gauge GPU KV Cache使用率
vllm:request_prompt_tokens Histogram 请求的Prompt Token数分布
vllm:request_generation_tokens Histogram 生成Token数分布
vllm:request_latency_seconds Histogram 请求延迟分布
小提示: 我建议把vllm:gpu_cache_usage_perc作为核心告警指标。超过80%就要注意了,超过90%基本离OOM不远了。我在项目中遇到过,Cache打满后模型直接崩了,所有请求都超时。

4.2 ServiceMonitor配置:让Prometheus自动发现

指标暴露出来了,但Prometheus怎么知道去抓?你想想看,K8s里Pod IP是动态的,总不能手动配吧。这时候ServiceMonitor就派上用场了。

先给vLLM服务打个标签,方便筛选:

apiVersion: v1
kind: Service
metadata:
  name: vllm-service
  labels:
    app: vllm
    monitoring: prometheus  # 关键标签
spec:
  selector:
    app: vllm
  ports:
  - name: http
    port: 8000
    targetPort: 8000
  - name: metrics
    port: 8080
    targetPort: 8080

然后创建ServiceMonitor:

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: vllm-monitor
  namespace: monitoring
spec:
  selector:
    matchLabels:
      app: vllm
      monitoring: prometheus
  endpoints:
  - port: metrics
    interval: 15s
    path: /metrics
  namespaceSelector:
    matchNames:
    - default
注意: 我曾经踩过一个坑——ServiceMonitor的namespace和Prometheus实例不在同一个namespace,导致抓取失败。解决办法是给ServiceMonitor加上namespaceSelector,或者把Prometheus的serviceMonitorNamespaceSelector设为空(匹配所有namespace)。

配置好后,Prometheus会自动发现vLLM Pod,每15秒抓一次指标。你可以在Prometheus UI的Target页面确认状态。

4.3 Grafana看板设计:从数据到决策

指标有了,数据进来了,但一堆数字谁看得懂?Grafana看板就是把这些数字变成直观的图表。我设计看板有个原则:一张图解决一个问题。别搞大而全的“监控大屏”,没用。

4.3.1 核心看板:推理服务健康总览

这个看板我放在第一个,值班人员扫一眼就知道服务状态。包含以下面板:

  • 请求吞吐量:使用rate(vllm:num_requests_running[1m]),看QPS趋势
  • 延迟P99:使用histogram_quantile(0.99, rate(vllm:request_latency_seconds_bucket[5m])),这是核心指标
  • GPU Cache使用率:直接展示vllm:gpu_cache_usage_perc,超过80%标黄,超过90%标红
  • 排队请求数vllm:num_requests_waiting,超过100就要关注了
关键公式: 延迟P99的计算很多人写错。记住要用rate()包一下,不然Histogram的累积值会一直增长,算出来的分位数不准。我刚开始也犯过这个错,查了半天才发现。

4.3.2 进阶看板:模型性能分析

这个看板用于排查模型本身的瓶颈。比如:

  • Prompt vs Generation Token分布:用两个Histogram叠加,看是输入长还是输出长
  • 每Token生成时间:用vllm:request_latency_seconds / vllm:request_generation_tokens,算每个Token的平均耗时
  • Batch Size变化:vLLM内部会动态调整Batch,这个指标能看出调度效率

你想想看,如果每Token生成时间突然变长,大概率是GPU显存带宽瓶颈,或者模型太大导致Cache命中率下降。

4.3.3 告警规则:别等用户投诉

看板是给人看的,但人不可能24小时盯着。告警才是真正的守护者。我常用的几条规则:

groups:
- name: vllm_alerts
  rules:
  - alert: HighCacheUsage
    expr: vllm:gpu_cache_usage_perc > 0.85
    for: 2m
    annotations:
      summary: "GPU Cache使用率超过85%"
      
  - alert: HighLatency
    expr: histogram_quantile(0.99, rate(vllm:request_latency_seconds_bucket[5m])) > 5
    for: 1m
    annotations:
      summary: "P99延迟超过5秒"
      
  - alert: QueueTooLong
    expr: vllm:num_requests_waiting > 200
    for: 30s
    annotations:
      summary: "排队请求超过200"
避坑指南: 我曾经把告警阈值设得太低,结果半夜被PagerDuty吵醒三次,一看只是正常流量波动。建议先用看板观察一周,摸清基线再设告警。另外,for参数别设太短,至少1-2分钟,避免毛刺误报。

4.4 知识体系总览

这一套东西串起来,就是下面这张图。我习惯用SVG画这种流程图,清晰直观。

vLLM Pod :8080/metrics K8s Service ServiceMonitor Prometheus Grafana AlertManager 图:vLLM Prometheus监控体系架构

这套体系搭好后,你基本能掌握vLLM的运行状态。下次再遇到推理变慢,不用猜,直接看Grafana,哪个指标异常一目了然。嗯,这就是监控的价值。

专注资料整理