Prometheus 是 CNCF 毕业项目,最初由 SoundCloud 开发,现已成为云原生指标监控的事实标准。它负责采集、存储、查询指标并触发告警,通常与 Grafana、Alertmanager、Exporter 和 Kubernetes 生态一起使用。
本文基于 Prometheus 3.x 重写,覆盖核心架构、数据模型、配置、PromQL、告警、Kubernetes 落地、生产容量、高可用、安全、自监控和 3.x 升级。最后复核时间:2026-10。
Prometheus 专注指标(metrics) ,不替代日志(Loki/ELK)和链路追踪(Tempo/Jaeger)。它也不是计费级精确系统,采集丢失、重启和网络分区都可能造成数据缺口。
Prometheus 简介 它解决什么问题
指标采集 :从应用、主机、中间件、Kubernetes 组件拉取时间序列数据。
多维数据模型 :用 metric name + labels 描述数据,支持灵活聚合和切片。
PromQL :强大的查询语言,可直接计算速率、分位数、错误预算等。
告警 :基于 PromQL 规则触发告警,交给 Alertmanager 分组、抑制、路由。
服务发现 :与 Kubernetes、Consul、DNS、文件等集成,目标自动上下线。
优势
单二进制、部署简单,不依赖外部数据库即可运行。
Pull 模型便于服务发现、目标健康检查和统一治理。
标签模型非常适合云原生和动态环境。
生态成熟:Exporter、Operator、Grafana、Alertmanager、Thanos/Mimir/VictoriaMetrics。
PromQL 表达能力强,适合做 SLO、容量分析和故障定位。
局限
本地 TSDB 不是分布式系统,单节点有容量上限。
默认不带认证授权,不能直接暴露公网。
不擅长高基数(high cardinality)数据,标签爆炸会导致 OOM 和查询变慢。
不适合做计费、审计、精确一次的数据统计。
日志和追踪需要其他系统配合。
长期存储、全局查询、跨集群聚合需要额外组件。
生态组件
组件
作用
Prometheus Server
采集、存储、查询、规则评估
Exporter
把第三方系统指标转成 Prometheus 格式
Pushgateway
短生命周期任务的推送中转
Alertmanager
告警分组、抑制、静默、路由、通知
Grafana
可视化与 Dashboard
Prometheus Operator
Kubernetes 上的 CRD 化部署与管理
Thanos / Mimir / VictoriaMetrics
长期存储、全局查询、高可用
Prometheus Agent
只采集和 remote write,不做本地查询
核心架构 ┌──────────────┐ ┌──────────────────┐ │ Targets │ │ Service Discovery │ │ exporters │────▶│ K8s / DNS / file │ │ apps / kubelet│ └────────┬─────────┘ └──────┬───────┘ │ │ scrape(pull) │ ▼ ▼ ┌─────────────────────────────────────┐ │ Prometheus Server │ │ Retrieval → TSDB → Rule Evaluation │ │ HTTP API / Query / UI │ └───────┬──────────────────┬──────────┘ │ │ │ alerts │ remote write ▼ ▼ ┌──────────────┐ ┌──────────────────┐ │ Alertmanager │ │ Long-term Store │ │ route/group │ │ Thanos/Mimir/VM │ └──────┬───────┘ └──────────────────┘ │ ▼ Email / Slack / PagerDuty / Webhook
核心模块
模块
说明
Retrieval
按 scrape_configs 拉取目标指标
TSDB
本地时序数据库,2 小时一个 block,WAL 保证崩溃恢复
Rule Evaluation
周期性执行 recording rules 和 alerting rules
HTTP API
查询、目标、规则、告警、状态等接口
Service Discovery
自动发现抓取目标
Remote Write/Read
与外部长期存储集成
Pull 与 Push Prometheus 默认是 Pull :
Prometheus 主动按周期抓取目标,天然知道目标是否存活(up 指标)。
目标不需要知道 Prometheus 地址,便于解耦和动态发现。
采集节奏、超时、并发由 Prometheus 统一控制。
Pushgateway 只用于短生命周期任务 :
cron、批处理、Serverless、CI Job 等可能在 Prometheus 抓取前就结束的任务。
Pushgateway 不会自动过期旧指标,任务结束后要主动删除对应 group。
不要用 Pushgateway 做长期服务的通用上报,也不要用它做高可用存储。
对实时性要求高的场景,优先缩短 scrape_interval 或使用 Agent/OTLP/remote write。
部署形态
形态
适用
单机 Prometheus
小规模、测试、边缘
Prometheus + remote write
本地短保留 + 长期存储
双副本 Prometheus
高可用采集,查询层去重
Prometheus Agent
多集群/边缘只采集转发
Prometheus Operator
Kubernetes 生产环境
Thanos/Mimir/VictoriaMetrics
全局查询、长期存储、大规模
数据模型 时间序列 Prometheus 中的数据是时间序列:
<metric_name>{<label_name>="<label_value>", ...} <value> <timestamp>
例如:
http_requests_total{job="api", instance="10.0.0.1:8080", method="GET", code="200"} 1024
metric name :指标名称,例如 http_requests_total。
labels :维度键值对,例如 job、instance、method、code。
sample :一个时间戳 + 一个 float64 值;直方图样本还包含 count/sum/buckets。
每个唯一的 label 组合都是一条独立时间序列。
命名规则 Prometheus 3.x 支持 UTF-8 metric/label 名称,但为了兼容性和可读性,建议遵循传统规则:
对象
推荐规则
示例
metric name
[a-zA-Z_:][a-zA-Z0-9_:]*
http_requests_total
label name
[a-zA-Z_][a-zA-Z0-9_]*
method、status_code
label value
UTF-8 字符串
GET、prod
counter 后缀
_total
process_cpu_seconds_total
时间单位
秒,后缀 _seconds
request_duration_seconds
字节单位
bytes,后缀 _bytes
node_memory_MemTotal_bytes
比例
0-1,后缀 _ratio
disk_usage_ratio
信息类指标
_info
build_info
不要把这些维度放进 metric name:http_get_users_total、http_post_users_total,应该用 http_requests_total{method="GET"}。
四种指标类型
类型
特点
典型用途
查询方式
Counter
只增不减,进程重启会归零
请求数、错误数、字节数
rate()、increase()
Gauge
可增可减
温度、内存、队列长度
直接查询、delta()、predict_linear()
Histogram
客户端分桶,服务端计算分位数
请求延迟、响应大小
histogram_quantile()
Summary
客户端计算分位数
单实例延迟观察
直接查询 quantile
Histogram 与 Summary
Histogram 暴露 _bucket{le="..."}、_count、_sum,可以跨实例、跨时间聚合,适合 SLO。
Summary 暴露 _count、_sum 和客户端计算好的分位数,不能跨实例聚合。
做服务端延迟 SLO 时优先 Histogram;Summary 适合单实例、客户端分位数已足够的场景。
Prometheus 3.x 支持 native histograms ,一个样本包含完整直方图,桶更细、存储更省;3.9 起原生直方图已稳定,抓取需在 scrape 配置中开启 scrape_native_histograms。
经典 Histogram 的 le 标签在 v3 中会被规范化(例如 1 变成 1.0),升级时要检查直接引用整数值的查询和告警。
基数 基数 = 唯一时间序列数量 。它由 metric 数量和 label 组合决定。
高基数标签的典型来源:
user_id、request_id、session_id、email
完整 URL、原始 IP、动态容器名
无界的错误信息、SQL 语句
每个请求都不同的标签值
高基数会导致:
内存和磁盘暴涨。
查询变慢,甚至 OOM。
scrape 变慢、规则评估超时。
远端存储成本上升。
治理手段:
从源头减少标签,不要把高基数字段做成 label。
用 metric_relabel_configs 丢弃或重写不需要的指标。
设置 sample_limit、label_limit、target_limit。
监控 prometheus_tsdb_head_series 和 scrape_samples_scraped。
对日志类、事件类数据使用日志系统,不要塞进 Prometheus。
安装与启动 二进制安装 从官方下载对应平台压缩包,解压后得到 prometheus、promtool:
tar xzf prometheus-*.tar.gz sudo install -m 0755 prometheus-*/prometheus /usr/local/bin/ sudo install -m 0755 prometheus-*/promtool /usr/local/bin/
创建配置目录和数据目录:
sudo mkdir -p /etc/prometheus /var/lib/prometheus sudo chown -R prometheus:prometheus /var/lib/prometheus
最小配置 global: scrape_interval: 15s evaluation_interval: 15s alerting: alertmanagers: - static_configs: - targets: [] rule_files: []scrape_configs: - job_name: prometheus static_configs: - targets: ["localhost:9090" ]
启动:
prometheus \ --config.file=/etc/prometheus/prometheus.yml \ --storage.tsdb.path=/var/lib/prometheus \ --storage.tsdb.retention.time=15d \ --web.listen-address=:9090
生产建议:
固定版本,不要使用 latest。
配置和数据目录分离,数据目录使用独立磁盘。
需要热加载时再加 --web.enable-lifecycle,并限制访问来源。
启动前执行 promtool check config /etc/prometheus/prometheus.yml。
systemd [Unit] Description =PrometheusAfter =network-on line.targetWants =network-on line.target[Service] User =prometheusGroup =prometheusType =simpleExecStart =/usr/local/bin/prometheus \ --config.file =/etc/prometheus/prometheus.yml \ --storage.tsdb.path =/var/lib/prometheus \ --storage.tsdb.retention.time =15 d \ --web.listen-address =:9090 Restart =on -failureRestartSec =5 [Install] WantedBy =multi-user.target
健康检查
接口
用途
GET /-/healthy
进程健康
GET /-/ready
可以接收查询
GET /metrics
Prometheus 自身指标
GET /api/v1/targets
抓取目标状态
GET /api/v1/rules
规则状态
GET /api/v1/alerts
当前告警
配置体系 配置结构 global: scrape_interval: 15s scrape_timeout: 10s evaluation_interval: 15s external_labels: cluster: prod replica: "0" rule_files: - /etc/prometheus/rules/*.yml alerting: alertmanagers: - static_configs: - targets: - alertmanager:9093 scrape_configs: - job_name: node static_configs: - targets: - node-1:9100 - node-2:9100 remote_write: - url: https://mimir.example.com/api/v1/push queue_config: max_samples_per_send: 10000
scrape_config 关键项
配置
说明
job_name
抓取任务名,默认写入 job 标签
scrape_interval
抓取周期,默认继承 global
scrape_timeout
单次抓取超时,不能大于 interval
metrics_path
指标路径,默认 /metrics
scheme
http 或 https
honor_labels
是否保留目标上报的 job/instance 标签
honor_timestamps
是否使用目标上报的时间戳
sample_limit
单次抓取最大样本数,超出则失败
label_limit
单个样本最大标签数
target_limit
最大目标数
body_size_limit
响应体大小限制
metric_relabel_configs
入库前对样本做 relabel
relabel_configs
抓取前对目标做 relabel
fallback_scrape_protocol
Content-Type 无效时的回退协议(v3 更严格)
relabel_configs 与 metric_relabel_configs
配置
作用阶段
典型用途
relabel_configs
发现目标后、抓取前
过滤目标、改写地址、添加标签
metric_relabel_configs
抓取后、入库前
丢弃高基数指标、重命名标签、过滤样本
常用 action:
action
作用
replace
正则匹配后替换 target_label
keep
只保留匹配的目标/样本
drop
丢弃匹配的目标/样本
labelmap
把匹配的标签名映射为新标签名
labeldrop
删除匹配的标签
labelkeep
只保留匹配的标签
hashmod
按哈希取模,用于分片
lowercase / uppercase
标签值大小写转换
示例:只抓取带注解的 Kubernetes Service,并丢弃高基数指标:
scrape_configs: - job_name: kubernetes-services kubernetes_sd_configs: - role: endpoints relabel_configs: - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape ] action: keep regex: "true" - source_labels: [__meta_kubernetes_namespace ] target_label: namespace - source_labels: [__meta_kubernetes_service_name ] target_label: service metric_relabel_configs: - source_labels: [__name__ ] regex: "go_.*" action: drop
配置校验与热加载 promtool check config /etc/prometheus/prometheus.yml promtool check rules /etc/prometheus/rules/*.yml curl -X POST http://localhost:9090/-/reload
注意:
/-/reload 需要 --web.enable-lifecycle。
配置错误时 reload 会失败,旧配置继续生效。
生产环境应把配置纳入 Git,CI 中执行 promtool check,避免手改。
存储参数
参数
说明
--storage.tsdb.path
数据目录
--storage.tsdb.retention.time
保留时间,默认 15d
--storage.tsdb.retention.size
保留大小,默认不限制
--storage.tsdb.wal-compression
WAL 压缩,新版本默认开启
--storage.tsdb.retention.size
建议不超过磁盘的 80%-85%,给 compaction 留空间
旧版的 --storage.tsdb.retention 已不再推荐,统一使用 .time 和 .size。
服务发现与 Relabel 常见服务发现
类型
适用
static_configs
固定目标,测试或小规模
file_sd_configs
文件动态更新,适合外部系统生成
dns_sd_configs
基于 DNS SRV/A 记录
kubernetes_sd_configs
Kubernetes 原生发现
consul_sd_configs
Consul 服务目录
http_sd_configs
通过 HTTP 接口返回目标列表
Kubernetes SD role
role
发现对象
典型用途
node
节点
node-exporter、kubelet
service
Service
blackbox 探针、Service 级监控
pod
Pod
直接抓取 Pod
endpoints
Endpoints
抓取 Service 后端
endpointslice
EndpointSlice
大规模集群,替代 endpoints
ingress
Ingress
Ingress 探针
常用 meta label:
__meta_kubernetes_namespace
__meta_kubernetes_pod_name
__meta_kubernetes_pod_label_<label>
__meta_kubernetes_service_name
__meta_kubernetes_service_annotation_<annotation>
__meta_kubernetes_node_name
__meta_kubernetes_endpoint_address_target_kind
这些 __meta_* 标签默认不会入库,需要在 relabel_configs 中转成正式标签。
Kubernetes 自动发现示例 scrape_configs: - job_name: kubernetes-pods kubernetes_sd_configs: - role: pod relabel_configs: - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape ] action: keep regex: "true" - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path ] action: replace target_label: __metrics_path__ regex: (.+) - source_labels: [__address__ , __meta_kubernetes_pod_annotation_prometheus_io_port ] action: replace regex: ([^:]+)(?::\d+)?;(\d+) replacement: $1:$2 target_label: __address__ - source_labels: [__meta_kubernetes_namespace ] target_label: namespace - source_labels: [__meta_kubernetes_pod_name ] target_label: pod - source_labels: [__meta_kubernetes_pod_label_app ] target_label: app
注解约定建议统一,例如:
metadata: annotations: prometheus.io/scrape: "true" prometheus.io/port: "8080" prometheus.io/path: "/metrics"
Relabel 注意事项
regex 默认是全匹配 ,不是包含匹配;需要包含时写成 .*foo.*。
replace 不匹配时不会写入。
labelmap 常用于把 __meta_kubernetes_pod_label_* 转成业务标签。
metric_relabel_configs 不作用于 up 等自动生成的时间序列。
不要保留 __meta_* 标签,否则会造成高基数和存储浪费。
honor_labels: true 适合 federation/Pushgateway,普通抓取一般保持 false。
PromQL 基础选择器 # 瞬时向量 http_requests_total{job="api", code="500"} # 正则匹配 http_requests_total{code=~"5.."} # 排除 http_requests_total{code!~"2..|3.."} # 区间向量 http_requests_total{job="api"}[5m] # 位移 http_requests_total{job="api"} offset 1h # @ 修饰符 http_requests_total{job="api"} @ 1609746000
常用函数
函数
用途
注意
rate(v[5m])
每秒平均增长率
窗口至少为 scrape interval 的 4 倍
irate(v[5m])
最后两个样本的瞬时增长率
噪声大,不建议用于告警
increase(v[5m])
区间增长量
会做外推,短窗口可能不准
delta(v[5m])
Gauge 区间差值
不适合 Counter
histogram_quantile(0.99, v)
经典直方图分位数
先 sum by (le) 聚合
absent(v)
指标缺失时返回 1
用于检测采集缺失
predict_linear(v[1h], 3600)
线性预测未来值
适合磁盘/容量告警
label_replace()
生成/改写标签
常用于补全 instance
label_join()
拼接标签
生成复合维度
topk(5, v)
取前 5
适合看热点
quantile(0.9, v)
聚合分位数
不是时间序列分位数
常见查询 实例存活
CPU 使用率 100 - ( avg by (instance) ( rate(node_cpu_seconds_total{mode="idle"}[5m]) ) * 100 )
内存使用率 1 - ( node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes )
文件系统使用率 1 - ( node_filesystem_avail_bytes{fstype!~"tmpfs|overlay"} / node_filesystem_size_bytes{fstype!~"tmpfs|overlay"} )
HTTP 5xx 比例 sum(rate(http_requests_total{job="api", code=~"5.."}[5m])) / sum(rate(http_requests_total{job="api"}[5m]))
p99 延迟(经典 Histogram) histogram_quantile( 0.99, sum by (le) ( rate(http_request_duration_seconds_bucket{job="api"}[5m]) ) )
SLO 错误预算燃尽率 ( sum(rate(http_requests_total{job="api", code=~"5.."}[1h])) / sum(rate(http_requests_total{job="api"}[1h])) ) / 0.001
表示 99.9% SLO 的 1 小时燃尽率。燃尽率 1 表示按当前速度会在 30 天内用完预算。
PromQL 常见坑
不要用平均值做延迟 SLO ,用比例或分位数。
不要对 Counter 直接求平均 ,先 rate。
不要用 irate 做告警 ,最后两个点波动大,容易误报。
rate 窗口太短 会没有足够样本,至少 2 个,建议 4 倍 scrape interval。
**histogram_quantile 前忘记 sum by (le)**,会得到每个实例的分位数而不是全局分位数。
标签不匹配导致空结果 :用 on() / ignoring() / group_left() 明确匹配关系。
高基数正则 :避免在查询里对大量序列做复杂正则。
记录规则 :重查询、Dashboard 常用查询、SLO 计算应沉淀为 recording rules。
Recording Rules 命名建议:level:metric:operations,例如:
groups: - name: api-slo interval: 30s rules: - record: job:http_requests:rate5m expr: sum by (job) (rate(http_requests_total[5m])) - record: job:http_errors:ratio5m expr: | sum by (job) (rate(http_requests_total{code=~"5.."}[5m])) / sum by (job) (rate(http_requests_total[5m]))
记录规则能降低查询成本,但会增加存储和规则评估开销,不要把所有查询都做成规则。
告警与 Alertmanager 告警规则 groups: - name: basic-alerts rules: - alert: InstanceDown expr: up == 0 for: 5m keep_firing_for: 5m labels: severity: critical team: sre annotations: summary: "实例 {{ $labels.instance }} 不可达" description: "{{ $labels.job }} / {{ $labels.instance }} 已持续 5 分钟无法抓取" runbook_url: "https://wiki.example.com/runbook/instance-down" - alert: HighHTTPErrorRate expr: | sum by (job) (rate(http_requests_total{code=~"5.."}[5m])) / sum by (job) (rate(http_requests_total[5m])) > 0.05 for: 10m labels: severity: warning annotations: summary: "{{ $labels.job }} 5xx 比例超过 5%"
要点:
for 避免瞬时抖动触发。
keep_firing_for 避免数据缺失导致告警误恢复。
severity、team、runbook_url 是告警可运维性的基础。
告警应基于用户症状 (错误率、延迟、不可用),而不是单纯 CPU 高。
每个 page 告警都应该是可行动的;不可行动的降级为 ticket 或 dashboard。
Alertmanager 配置 global: resolve_timeout: 5m route: receiver: default group_by: [alertname , cluster , job ] group_wait: 30s group_interval: 5m repeat_interval: 4h routes: - matchers: - severity="critical" receiver: pagerduty continue: true - matchers: - team="database" receiver: db-team receivers: - name: default webhook_configs: - url: https://hooks.example.com/alert - name: pagerduty pagerduty_configs: - service_key_file: /etc/alertmanager/pagerduty-key - name: db-team email_configs: - to: db-team@example.com from: alertmanager@example.com smarthost: smtp.example.com:587
关键概念:
概念
作用
route
告警路由树
receiver
通知渠道
group_by
分组维度
group_wait
首次分组等待
group_interval
同组更新间隔
repeat_interval
重复通知间隔
inhibit_rules
高优先级告警抑制低优先级
silence
临时静默
抑制示例:主机宕机时,抑制该主机上的所有实例告警。
inhibit_rules: - source_matchers: [alertname="NodeDown" ] target_matchers: [alertname="InstanceDown" ] equal: [instance ]
Alertmanager 高可用
多个 Alertmanager 组成 gossip 集群,配置相同。
Prometheus 双副本分别发送告警,Alertmanager 负责去重。
使用共享存储或配置管理保证配置一致。
监控通知失败率、队列积压、集群成员状态。
amtool check-config /etc/alertmanager/alertmanager.yml amtool alert query amtool silence add alertname="InstanceDown" --duration=2h
Kubernetes 监控 推荐方式:Prometheus Operator 生产环境不建议手写 Deployment + ConfigMap。推荐使用 kube-prometheus-stack 或 Prometheus Operator,把监控组件 CRD 化:
CRD
作用
Prometheus
Prometheus 实例、副本、存储、保留
Alertmanager
Alertmanager 集群
ServiceMonitor
声明式抓取 Service
PodMonitor
声明式抓取 Pod
Probe
blackbox 探针
PrometheusRule
告警/记录规则
AlertmanagerConfig
告警路由与接收器
核心组件
组件
作用
node-exporter
节点 CPU、内存、磁盘、网络
kube-state-metrics
Kubernetes 对象状态(Deployment、Pod、PVC 等)
kubelet / cAdvisor
容器资源指标
blackbox-exporter
HTTP/TCP/ICMP/DNS 探针
kube-apiserver / etcd / scheduler
控制面指标
ServiceMonitor 示例 apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: name: api namespace: monitoring labels: release: kube-prometheus-stack spec: namespaceSelector: matchNames: [prod ] selector: matchLabels: app: api endpoints: - port: metrics interval: 15s path: /metrics scheme: http relabelings: - sourceLabels: [__meta_kubernetes_service_name ] targetLabel: service
PrometheusRule 示例 apiVersion: monitoring.coreos.com/v1 kind: PrometheusRule metadata: name: api-rules namespace: monitoring labels: release: kube-prometheus-stack spec: groups: - name: api rules: - alert: APIHighErrorRate expr: | sum by (service) (rate(http_requests_total{code=~"5.."}[5m])) / sum by (service) (rate(http_requests_total[5m])) > 0.05 for: 10m labels: severity: warning annotations: summary: "{{ $labels.service }} 5xx 比例过高"
标签规范 建议统一以下标签,便于跨集群聚合:
cluster:集群名
environment:prod/staging/dev
region:区域
namespace:Kubernetes 命名空间
pod:Pod 名
container:容器名
service:服务名
version:版本(谨慎使用,避免高基数)
不要使用 pod 作为长期聚合维度,Pod 名会频繁变化导致高基数;聚合时优先用 service、namespace、cluster。
RBAC 与安全
Prometheus 需要访问 Kubernetes API 做服务发现,使用最小权限的 ServiceAccount。
nodes/proxy 权限较强,只在需要抓取 kubelet/cAdvisor 时授予。
使用 NetworkPolicy 限制 Prometheus 的出入流量。
不要在公网暴露 Prometheus UI/API。
ServiceMonitor/PodMonitor 的 namespaceSelector 要限制范围,避免误抓全集群。
生产实践 容量规划 Prometheus 的资源消耗主要取决于:
活跃时间序列数(active series) :决定内存。
每秒采样数(samples/sec) :决定 CPU 和磁盘写入。
保留时间 :决定磁盘。
查询复杂度 :决定查询内存和 CPU。
粗略磁盘公式:
磁盘 ≈ 保留秒数 × 每秒采样数 × 每样本字节数
官方给出的平均样本大小约为 1-2 bytes,但实际要以压测和 promtool tsdb analyze 为准。
建议:
单 Prometheus 的 active series 控制在百万级以内,超过后考虑分片。
内存按 active series 估算,并留 30%-50% 余量。
不要给 Prometheus 设置过低的 memory limit,否则容易 OOMKill。
使用 --storage.tsdb.retention.size 限制磁盘,建议不超过磁盘的 80%-85%,给 compaction 留空间。
数据盘使用本地 SSD,避免网络存储导致 WAL/compaction 抖动。
基数治理 优先从应用埋点解决:
不给每个用户、请求、URL 打标签。
错误信息、SQL、堆栈不要做 label。
用固定枚举描述状态,不要用自由文本。
高基数字段放到日志或追踪系统。
采集侧治理:
scrape_configs: - job_name: app sample_limit: 50000 label_limit: 30 target_limit: 5000 metric_relabel_configs: - source_labels: [__name__ ] regex: "http_request_duration_seconds_bucket" action: keep - source_labels: [user_id ] action: labeldrop
监控指标:
prometheus_tsdb_head_series
scrape_samples_scraped
scrape_series_added
prometheus_tsdb_head_samples_appended_total
抓取与查询调优
scrape_interval 常用 15s-30s;不要盲目设成 1s。
scrape_timeout 必须小于 scrape_interval,通常为 interval 的 50%-80%。
rate() 窗口至少为 scrape interval 的 4 倍,避免样本不足。
告警用 rate,不要用 irate。
重查询沉淀为 recording rules。
限制 Dashboard 时间范围和查询并发。
设置 --query.timeout、--query.max-samples,防止单条查询拖垮实例。
使用 promtool query instant / promtool query range 做离线排查。
TSDB 与备份 TSDB 结构:
每 2 小时生成一个 block。
当前 block 在内存中,通过 WAL 保证崩溃恢复。
后台 compaction 合并小 block,最大跨度约为保留时间的 10% 或 31 天。
compaction 期间新旧 block 同时存在,磁盘需要额外空间。
备份建议:
curl -X POST http://localhost:9090/api/v1/admin/tsdb/snapshot
使用 snapshot 备份,不要直接复制正在写入的 TSDB 目录。
同时备份配置、规则、Alertmanager 配置和 Dashboard。
定期做恢复演练。
升级前先备份。
SLO 告警 Prometheus 非常适合做 SLO:
用 recording rules 计算 SLI。
用多窗口燃尽率告警减少噪音。
将错误预算和告警路由到对应团队。
与 SRE 的 SLO/错误预算流程结合,而不是只配静态阈值。
示例 recording rules:
groups: - name: slo-api interval: 30s rules: - record: job:slo_errors:ratio5m expr: | sum by (job) (rate(http_requests_total{code=~"5.."}[5m])) / sum by (job) (rate(http_requests_total[5m])) - record: job:slo_burn_rate1h expr: job:slo_errors:ratio5m / 0.001
高可用与长期存储 本地 TSDB 不是高可用 Prometheus 本地存储是单节点数据库,不做复制。磁盘损坏或节点故障会丢失数据。
常见高可用方案:
双副本 Prometheus :两个实例抓相同目标,配置 external_labels.replica 区分。
remote write 到长期存储 :Thanos、Mimir、VictoriaMetrics 等。
查询层去重 :Thanos Querier/Mimir 根据 replica 标签去重。
Alertmanager 集群 :多个 Alertmanager 组成 gossip 集群。
注意:
双副本会带来双倍采集和存储成本。
两个副本的 external_labels 必须包含唯一 replica。
不要让两个 Prometheus 写同一个本地 TSDB 目录。
告警规则在两个副本都会评估,依靠 Alertmanager 去重。
长期存储选型
方案
特点
适用
Thanos
Sidecar/Receiver + 对象存储,生态成熟
已有 Prometheus,想要全局查询
Grafana Mimir
水平扩展、多租户、兼容 Prometheus
大规模、多团队
VictoriaMetrics
高性能、压缩好、部署相对简单
高基数、成本敏感
Cortex
早期方案,现多转向 Mimir
历史项目
Federation Federation 适合聚合指标 ,不适合做高可用或全量长期存储:
上级 Prometheus 抓取下级 Prometheus 的 /federate。
只应抓取少量聚合指标,避免把高基数数据全量上卷。
跨集群全量查询优先 Thanos/Mimir/VictoriaMetrics。
Agent 模式 Prometheus Agent:
只负责采集和 remote write,不做本地查询。
适合边缘集群、多集群采集、降低中心 Prometheus 压力。
使用 --agent 启动(v3 中不再使用 feature flag)。
安全 Prometheus 默认没有认证和授权 ,必须假设 UI/API 一旦暴露就等于指标数据泄露。
保护 Web UI/API
使用 --web.config.file 配置 TLS 和 basic auth。
或放在反向代理后面,使用 OIDC/OAuth2/SSO。
只监听内网地址,配 NetworkPolicy/防火墙。
不要用 NodePort/LoadBalancer 直接把 9090 暴露到公网。
web-config.yml 示例:
tls_server_config: cert_file: /etc/prometheus/server.crt key_file: /etc/prometheus/server.key basic_auth_users: admin: "$2y$10$..."
启动:
prometheus --web.config.file=/etc/prometheus/web-config.yml
敏感管理接口
参数
风险
--web.enable-lifecycle
允许 reload/quit,需限制访问
--web.enable-admin-api
允许删除数据、创建 snapshot,风险高
--web.enable-remote-write-receiver
允许外部写入,需认证和限流
生产环境按需开启,不要默认全开。
抓取安全
使用 HTTPS 抓取敏感目标。
使用 bearer_token_file、tls_config、basic_auth,不要把密钥写进 YAML 明文。
为 Prometheus 配置最小权限的 ServiceAccount。
对 Exporter 做网络隔离,避免暴露到公网。
监控 up 和证书到期时间。
Alertmanager 安全
Alertmanager 同样默认无认证,使用反向代理或 --web.config.file。
Webhook 使用 HTTPS,并校验接收端证书。
PagerDuty/Slack token 放在 secret 文件或 Secret Manager。
限制 silence 创建权限,避免误静默。
自监控与排错 关键自监控指标
指标
说明
up
目标是否可达
scrape_duration_seconds
抓取耗时
scrape_samples_scraped
单次抓取样本数
scrape_series_added
新增序列数
prometheus_tsdb_head_series
活跃序列数
prometheus_tsdb_head_samples_appended_total
写入样本速率
prometheus_tsdb_storage_blocks_bytes
block 占用
prometheus_tsdb_compactions_failed_total
compaction 失败
prometheus_rule_evaluation_duration_seconds
规则评估耗时
prometheus_rule_evaluation_failures_total
规则评估失败
prometheus_notifications_errors_total
告警发送失败
alertmanager_notifications_failed_total
Alertmanager 通知失败
process_resident_memory_bytes
进程内存
go_goroutines
goroutine 数
建议告警:
up == 0 持续 5 分钟。
scrape_duration_seconds 接近 scrape_timeout。
prometheus_tsdb_head_series 突增。
磁盘剩余空间不足。
规则评估失败或耗时过长。
Alertmanager 通知失败。
排错表
现象
常见原因
排查
Target 显示 DOWN
网络、端口、路径、TLS、认证
手动 curl、看 scrape_duration_seconds
context deadline exceeded
目标响应慢或超时太短
检查目标性能,调整 scrape_timeout
401/403
token/证书/权限
检查 bearer_token_file、RBAC
查询无数据
标签不匹配、时间范围、指标未采集
用 /api/v1/targets、up、原始指标排查
内存暴涨/OOM
高基数、查询过大、规则过重
看 head_series、scrape_samples_scraped
查询很慢
大范围、高基数、正则、缺 recording rule
缩小范围、加规则、优化 PromQL
告警不触发
expr 错、for 未满足、规则未加载
/api/v1/rules、promtool check rules
告警不发送
Alertmanager 路由/凭据/网络
amtool、Alertmanager 日志、通知指标
TSDB 异常
磁盘满、损坏、版本不兼容
备份、promtool tsdb analyze、日志
数据重复
多副本未去重、重复抓取
检查 replica 标签和抓取配置
常用命令与接口 promtool check config prometheus.yml promtool check rules rules/*.yml promtool query instant http://localhost:9090 'up == 0' promtool query range http://localhost:9090 'rate(http_requests_total[5m])' \ --start=2026-10-23T00:00:00Z --end=2026-10-23T01:00:00Z --step=1m promtool tsdb analyze /var/lib/prometheus curl http://localhost:9090/-/healthy curl http://localhost:9090/-/ready curl http://localhost:9090/api/v1/targets curl http://localhost:9090/api/v1/rules curl http://localhost:9090/api/v1/alerts curl http://localhost:9090/api/v1/status/tsdb
升级到 Prometheus 3.x Prometheus 3.0 包含一些不兼容变更,升级前务必阅读官方 migration guide。
主要变化
变化
影响
处理
移除部分 feature flags
promql-at-modifier、promql-negative-offset、agent、remote-write-receiver 等
改用默认行为或新参数
Agent 模式
--enable-feature=agent 改为 --agent
修改启动参数
Remote write receiver
改为 --web.enable-remote-write-receiver
修改启动参数
auto-gomemlimit
v3 自动根据容器内存设置 GOMEMLIMIT
可用 --no-auto-gomemlimit 关闭
UTF-8 名称
metric/label 名称支持 UTF-8
需要兼容旧校验时设 metric_name_validation_scheme: legacy
le/quantile 规范化
整数值会变成浮点表示,如 le="1" → le="1.0"
修改直接引用整数值的查询/告警
Content-Type 更严格
无效 Content-Type 会导致抓取失败
配置 fallback_scrape_protocol
holt_winters 重命名
改为 double_exponential_smoothing,需 feature flag
修改 PromQL
remote write HTTP/2 默认关闭
需要时显式开启
设置 enable_http2: true
原生直方图稳定
3.9 起 native-histograms flag 不再需要
通过 scrape_native_histograms 控制抓取
升级步骤
备份 TSDB、配置、规则、Alertmanager 配置和 Dashboard。
阅读当前版本到目标版本的 migration guide 和 changelog。
在 staging 环境升级 Prometheus、Alertmanager、Exporter、Operator。
执行 promtool check config 和 promtool check rules。
检查启动参数中是否还有已移除的 flag。
检查 Dashboard、告警和 recording rules 是否依赖旧的 le/quantile 值。
验证抓取目标的 Content-Type,必要时配置 fallback_scrape_protocol。
观察 up、抓取耗时、规则评估、查询延迟和内存。
准备回滚方案。
最佳实践清单
参考资料