3、Prometheus 基础:架构原理、数据模型、Pull vs Push 模式、安装与基本配置

好,咱们进入 Prometheus 的世界。说实话,在云原生监控这个领域,Prometheus 几乎成了事实标准。我最早接触它是在 2016 年,那时候还在用 Zabbix 和 Open-Falcon,第一次看到 Prometheus 的 Pull 模型时,心里想的是:「这玩意儿能行吗?」后来实践证明,它不仅行,而且非常行。

3.1 架构原理:一张图看懂 Prometheus

Prometheus 的架构,说白了就是「中心化采集 + 主动拉取 + 多维存储」。我习惯把它拆成四个核心组件:

  • Prometheus Server:核心大脑,负责拉取数据、存储、查询
  • Exporter:数据采集代理,暴露 /metrics 端点
  • Alertmanager:告警管理,处理告警路由、去重、静默
  • Pushgateway:临时任务的数据中转站(后面会细说)

整个工作流是这样的:

  1. Prometheus Server 定期从配置好的 Target(目标)拉取指标数据
  2. 数据经过解析、压缩后存入本地 TSDB(时序数据库)
  3. 用户通过 PromQL 查询数据,或触发告警规则
  4. Alertmanager 接收告警,发送通知

嗯,这里要注意一点:Prometheus 是单机架构,没有内置集群方案。我见过不少团队一上来就想搞集群,其实对于大多数场景,单机 Prometheus 配合联邦集群完全够用。我曾经在某个日活千万的平台上,单机 Prometheus 扛了 200 万时间序列,跑了两年没出过问题。

3.2 数据模型:标签才是灵魂

Prometheus 的数据模型,核心就两样东西:指标名和标签。

一个典型的时序数据长这样:

http_requests_total{method="GET", endpoint="/api/v1/users", status="200"} 1024

这里 http_requests_total 是指标名,花括号里的是标签。标签是键值对,用来区分不同的维度。你想想看,如果没有标签,我们只能看到「总请求数」,有了标签就能看到「每个接口、每个方法、每个状态码的请求数」。

Prometheus 支持四种指标类型:

类型 说明 典型场景
Counter 只增不减的计数器 请求数、错误数、CPU 时间
Gauge 可增可减的测量值 内存使用率、连接数、温度
Histogram 分桶统计,计算分位数 请求延迟分布、响应大小
Summary 类似 Histogram,但客户端计算分位数 预计算的分位数场景

我个人习惯把 Counter 和 Gauge 当成「基础款」,Histogram 和 Summary 是「进阶款」。刚开始用的时候,80% 的场景用 Counter 和 Gauge 就够了。

小技巧:标签的基数(Cardinality)要控制好。我曾经见过一个团队把用户 ID 作为标签,结果时间序列数量直接爆炸,Prometheus 内存撑爆了。标签值的高基数(比如超过 10 万)是 Prometheus 的杀手。

3.3 Pull vs Push:为什么 Prometheus 选择了 Pull?

这是个经典问题。我面试 SRE 时经常问:「Prometheus 为什么用 Pull 而不是 Push?」

Pull 模式的核心思想是:监控系统主动去拉取数据。每个被监控的服务暴露一个 /metrics 端点,Prometheus Server 定期去访问。

优点很明显:

  • 可控性强:监控系统决定拉取频率,不会因为被监控端突发数据导致过载
  • 健康检查:拉不到数据说明服务挂了,天然就是告警信号
  • 配置简单:只需要知道 Target 地址,不需要在被监控端安装 Agent

但 Pull 模式也有短板:

  • 网络可达性:Prometheus 必须能访问到 Target,跨网络或防火墙场景麻烦
  • 临时任务:批处理任务、短生命周期任务,还没等到拉取就结束了

这时候 Pushgateway 就派上用场了。它是个中间代理,临时任务把数据 Push 到 Pushgateway,Prometheus 再从 Pushgateway 拉取。说白了就是「用 Push 的方式模拟 Pull」。

避坑指南:我曾经在某个数据 pipeline 中大量使用 Pushgateway,结果发现它成了单点故障和性能瓶颈。Pushgateway 适合临时任务,不适合长期运行的 Service。另外,Pushgateway 不会自动清理过期数据,需要手动管理。

3.4 安装与基本配置:5 分钟跑起来

安装 Prometheus 其实很简单。我习惯用二进制方式,因为 Docker 方式虽然方便,但调试时不如二进制直观。

3.4.1 二进制安装

# 下载最新版(以 2.45.0 为例)
wget https://github.com/prometheus/prometheus/releases/download/v2.45.0/prometheus-2.45.0.linux-amd64.tar.gz

# 解压
tar xvf prometheus-2.45.0.linux-amd64.tar.gz
cd prometheus-2.45.0.linux-amd64

# 启动
./prometheus --config.file=prometheus.yml

启动后访问 http://localhost:9090,就能看到 Prometheus 的 Web UI 了。

3.4.2 基本配置

核心配置文件 prometheus.yml 长这样:

global:
  scrape_interval: 15s      # 全局拉取间隔
  evaluation_interval: 15s  # 告警规则评估间隔

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

  - job_name: 'node_exporter'
    static_configs:
      - targets: ['192.168.1.100:9100']

这里我解释几个关键点:

  • scrape_interval:拉取频率,默认 1 分钟,我一般设 15 秒
  • evaluation_interval:告警规则检查频率,通常和拉取频率一致
  • job_name:一组 Target 的逻辑分组,会自动添加 job 标签

3.4.3 添加 Node Exporter

要监控服务器指标,需要 Node Exporter:

# 下载并启动 Node Exporter
wget https://github.com/prometheus/node_exporter/releases/download/v1.6.0/node_exporter-1.6.0.linux-amd64.tar.gz
tar xvf node_exporter-1.6.0.linux-amd64.tar.gz
cd node_exporter-1.6.0.linux-amd64
./node_exporter

然后在 Prometheus 配置里加上:

  - job_name: 'node_exporter'
    static_configs:
      - targets: ['localhost:9100']

重启 Prometheus,就能在 Targets 页面看到新加入的节点了。

核心要点:Prometheus 的配置遵循「约定优于配置」原则。默认配置就能用,但生产环境建议调整 scrape_interval、添加合理的标签、配置数据保留时间(--storage.tsdb.retention.time)。

3.5 生产环境注意事项

最后分享几个我在生产环境踩过的坑:

  • 数据保留:默认保留 15 天,如果磁盘不够,记得调整 --storage.tsdb.retention.size
  • 内存管理:Prometheus 的内存和活跃时间序列数成正比,监控 100 万时间序列大概需要 8-16GB 内存
  • 存储性能:SSD 是必须的,HDD 在大量写入时容易成为瓶颈
  • 安全加固:默认没有认证,生产环境一定要加反向代理或使用 Prometheus 的 basic_auth

嗯,Prometheus 的基础就这些。说白了,它就是一个「定时去拿数据、存下来、让你查」的系统。但正是这种简洁的设计,让它成为了云原生监控的基石。下一章我们会深入 PromQL,看看怎么从这些数据中挖出有价值的信息。