Learn
Prometheus/01-what-is-prometheus

什么是 Prometheus

💡🤖 AI 时代,还要学 Prometheus 吗?学到什么程度?

必要,但同样概念级加会读即可。告警规则、PromQL、抓取配置可让 AI 生成,但「什么该做成指标、基数爆炸为何会打崩集群、告警阈值怎么定」需要你真正懂时序监控的边界,否则 AI 配的规则只会制造噪声或漏报。建议目标:理解时序数据模型、Pull 模型与标签基数的坑,能读懂仪表盘并判断指标设计是否合理。

Prometheus 是一个开源的监控系统 + 时序数据库(TSDB),2012 年诞生于 SoundCloud,2016 年成为 CNCF 继 Kubernetes 之后的第二个毕业项目。今天它几乎是云原生世界里指标监控的事实标准。

一句话概括它的工作方式:周期性地去目标服务的 HTTP 接口把指标「拉」回来,存进本地时序数据库,然后用 PromQL 查询、画图和告警。

ℹ️Prometheus 只管 Metrics

Prometheus 是可观测性三大支柱里 Metrics(指标) 那一根柱子。它不存日志(那是 Loki / ELK 的事),也不存链路(那是 Tempo / Jaeger 的事)。想清楚这个边界,能省掉很多「为什么 Prometheus 查不到我的日志」的困惑。

1. 为什么监控需要专门的时序数据库

新手常问:监控数据存 MySQL 不行吗?技术上行,实践上灾难。因为监控数据的形态和业务数据完全不同。

假设你有 500 台机器,每台采集 200 个指标,每 15 秒一次:

500 台 × 200 指标 × (60 / 15) 次/分 = 400,000 个数据点/分钟
                                   ≈ 5.76 亿个数据点/天

这类数据有四个鲜明特征:

特征说明对存储的要求
写多读少持续高频写入,查询只在排查/看板时发生写入路径必须极轻量
只追加几乎从不 UPDATE / DELETE 单条记录不需要复杂的事务与行级锁
按时间访问查询永远带时间范围(最近 1h、昨天同期)按时间分块存储,快速裁剪
数值高度相似相邻样本值接近、时间戳等差可做极致压缩

关系型数据库为「随机读写 + 事务 + 强一致」优化,付出的是每行几十字节的存储与索引开销。而时序数据库利用上述特征做了针对性设计:

  • 差分 + 变长编码(Gorilla 压缩):时间戳存差值的差值,浮点值存 XOR 后的有效位。Prometheus 实测平均每个样本只占 1–2 字节,而在 MySQL 里同样一条记录轻松超过 50 字节。
  • 按时间分块(block):默认每 2 小时一个块,查「最近 1 小时」只需读最新的块,老数据整块删除即可过期。
  • 倒排索引找序列:先用标签索引定位到「哪些时间序列」,再在这些序列里按时间扫描,避免全表扫描。
💡压缩带来的直观差距

按 1.5 字节/样本估算,上面例子的 5.76 亿点/天只占约 0.8 GB/天。同样的数据塞进 MySQL(含索引)大概率要 30 GB 以上,还查不动。这就是为什么监控要用专门的 TSDB。

2. Pull vs Push:Prometheus 的 Pull 哲学

大多数传统监控(Zabbix Agent 主动模式、StatsD、Graphite)是 Push 模型:被监控方主动把数据推给服务端。Prometheus 反其道而行,采用 Pull(拉取)模型:

Push 模型:  应用 ──推送──▶ 监控服务端
Pull 模型:  监控服务端 ──HTTP GET /metrics──▶ 应用

Prometheus 会按配置的间隔(默认 15s)去访问每个目标的 /metrics 接口,把返回的文本解析成样本存起来。这个动作叫 scrape(抓取)。

Pull 的优点

  • 目标存活天然可观测:抓不到就说明目标挂了。Prometheus 会自动为每个目标生成一个 up 指标(1 = 抓取成功,0 = 失败),你几乎不用额外写探活逻辑。Push 模型下「没收到数据」有歧义——是服务挂了,还是网络断了,还是它本来就不发?

  • 配置集中在服务端:谁被监控、多久抓一次,全部写在 Prometheus 的配置文件里。上千个应用不需要每个都配一遍服务端地址。

  • 可手动调试:任何时候你都能自己 curl 一下目标接口,看到和 Prometheus 完全一样的数据。这对排查「指标为什么不对」极其友好。

    # 你看到的,就是 Prometheus 看到的
    curl -s http://10.0.0.12:9100/metrics | head -20
  • 不会被打垮:抓取速率由服务端控制。Push 模型下,一次流量洪峰可能让上万实例同时猛推数据,把监控系统冲垮——而监控系统恰恰应该在故障时最稳。

  • 易于做多副本 / 分层:跑两个配置相同的 Prometheus 就得到了高可用,它们各自去拉,互不干扰。

Pull 的局限

Pull 不是银弹,它有几个明确的短板:

  • 短生命周期任务:一个跑 3 秒就结束的 CronJob,Prometheus 根本来不及抓。这类场景需要 Pushgateway 中转(第 2 章详述)。
  • 网络可达性要求:Prometheus 必须能主动连到每个目标。目标在 NAT 后面、在客户端设备上、跨越严格防火墙时,Pull 就很别扭。
  • 事件类数据不适合:Pull 拿到的是「此刻的状态快照」。两次抓取之间发生的瞬时尖峰会被抹平,单次业务事件(一笔订单)也不该用指标来记——那是日志/数仓的活。
⚠️别把 Pull 当信仰

Pull 与 Push 的争论常被过度神化。真实工程里 Prometheus 生态两者都用:绝大多数场景 Pull,短任务用 Pushgateway,超大规模跨机房用 remote_write(本质是 Push 到长期存储)。选型看场景,不看教条。

3. 核心概念:时序、样本、标签、指标名

这四个词会贯穿整个教程,先建立准确的直觉。看一行真实的 /metrics 输出:

http_requests_total{job="api", method="GET", status="200"} 1342
  • 指标名(metric name):http_requests_total。回答「测的是什么」。
  • 标签(label):job="api"、method="GET"、status="200"。回答「是哪一维度的」,是一组键值对。
  • 时序(time series):指标名 + 一组标签唯一确定一条时间序列。上面这行就属于一条特定的序列。只要有任何一个标签的值不同(比如 status="500"),那就是另一条独立的序列。
  • 样本(sample):这条序列在某个时刻的一个数据点,形如 (时间戳, 值)。值永远是 float64,时间戳精确到毫秒。

用一张图理解它们的层级关系:

指标名 http_requests_total
  ├── 序列 A: {method="GET",  status="200"}
  │     └── 样本: (10:00:00, 1342) (10:00:15, 1360) (10:00:30, 1389) ...
  ├── 序列 B: {method="GET",  status="500"}
  │     └── 样本: (10:00:00,    3) (10:00:15,    3) (10:00:30,    7) ...
  └── 序列 C: {method="POST", status="200"}
        └── 样本: (10:00:00,  221) (10:00:15,  230) (10:00:30,  244) ...

有了标签,查询就变成了「多维切片」。在 PromQL 里:

# 全部序列
http_requests_total
 
# 只要 500 的那条
http_requests_total{status="500"}
 
# 按 method 维度聚合出每秒请求数
sum by (method) (rate(http_requests_total[5m]))
⚠️标签是把双刃剑

每多一个标签取值组合,就多一条独立时间序列,这叫基数(cardinality)。给指标打上 user_id 或 request_id 这类标签,会瞬间制造上百万条序列,直接把 Prometheus 内存打爆。标签值必须是有限且低基数的集合。第 4 章会专门展开。

4. 与其他方案的粗线条对比

维度PrometheusZabbixInfluxDB商业 APM(Datadog / New Relic)
定位云原生指标监控传统主机/网络监控通用时序数据库一站式可观测性 SaaS
数据模型指标名 + 多维标签主机 + Item(层级式)measurement + tag + field指标 + 标签(类似 Prom)
采集方式Pull 为主Agent Push / Server Pull 皆可主要 Push(Telegraf)Agent Push
查询语言PromQL(专为指标设计)触发器表达式(较弱)InfluxQL / Flux各家私有
服务发现原生支持 K8s / Consul / 云厂商需自动注册,较繁琐无,靠采集端Agent 自动发现
告警内置规则 + Alertmanager内置,功能完备需搭配 Kapacitor内置,开箱即用
长期存储本地盘为主,长期需 Thanos/Mimir依赖 MySQL/PG自带(含集群版,商业)SaaS 托管
成本免费,但要自己运维免费,运维成本中开源版单机按主机/数据量计费,昂贵

几句大白话总结:

  • Zabbix 强在传统 IDC:网络设备 SNMP、硬件告警、开箱即用的模板库。但它的数据模型是「主机 → 监控项」的树形结构,面对「一个服务 50 个动态 Pod」这种云原生场景会非常吃力。
  • InfluxDB 是通用 TSDB,更适合 IoT 传感器、业务埋点这类需要写入任意时序数据的场景,也支持字符串等非数值类型。但它自己不做服务发现和抓取,需要 Telegraf 配合;开源版还没有高可用。
  • 商业 APM 胜在省心:装个 Agent,指标、日志、链路、代码级火焰图全都有。代价是账单——按主机数或指标基数计费,规模上来后一年几十万人民币很常见,且数据在别人手里。
  • Prometheus 的甜点区是云原生动态环境:容器随时起停、IP 随时变化,靠服务发现自动跟上;多维标签 + PromQL 能回答任意切片的问题。代价是你要自己搞定高可用与长期存储。

5. 什么时候该用,什么时候不该

适合用 Prometheus

  • Kubernetes / 容器化环境:几乎是标配,服务发现能力天生契合。
  • 微服务的黄金指标监控:QPS、延迟、错误率、饱和度(RED / USE 方法)。
  • 主机与中间件监控:node_exporter、mysqld_exporter、redis_exporter 等生态极其丰富,装上即用。
  • 需要灵活多维分析:「北京机房 v2 版本的 POST 接口 5xx 率」这类问题,PromQL 一行就能回答。
  • 希望告警规则纳入 Git 管理:规则就是 YAML 文件,天然可 Code Review、可版本化。

不适合用 Prometheus

  • 需要 100% 精确的计费/审计数据。Prometheus 为可用性牺牲了准确性:抓取可能丢失、可能被采样、重启可能丢一小段 WAL。它是一个「足够准确」的系统,不是账本。 计费请走消息队列 + 数据库。
  • 单个事件的明细追溯。想查「订单 #12345 到底发生了什么」,那是日志和链路的活。指标只有聚合后的数值。
  • 高基数标签场景。用户 ID、会话 ID、URL 全路径、邮箱……这些进标签必炸。
  • 超长期存储需求。原生 Prometheus 默认保留 15 天,设计上就是为短期高频查询服务。要存一年,得上 Thanos、Mimir 或 VictoriaMetrics。
  • 日志检索。反复强调一次:Prometheus 不是日志系统。
  • 非数值型数据。样本值只能是 float64,存不了字符串状态。变通做法是把状态编码进标签,值恒为 1(这种叫 info 指标)。
💡一个判断口诀

问自己两个问题:① 这个数据我关心的是趋势和聚合,还是每一条明细?② 它的维度组合是几十个,还是无上限?

只有「关心趋势 + 维度可控」的数据,才该进 Prometheus。


🎯练习 1:判断数据该不该进 Prometheus

下面 5 类数据,判断哪些适合作为 Prometheus 指标采集,哪些不适合,并说明理由:

  1. 每台服务器的 CPU 使用率
  2. 每笔支付订单的金额与订单号
  3. 接口 /api/order 按 HTTP 状态码分类的请求数
  4. 用户登录时的完整 User-Agent 字符串
  5. Redis 当前连接数
🎯练习 2:解释 Pull 模型的取舍

用你自己的话回答:

  1. 为什么说 Pull 模型让「目标存活」变得天然可观测?Push 模型下同样的判断难在哪?
  2. 举一个 Pull 模型明显不好用的场景,并说明 Prometheus 生态如何补救。
🎯练习 3:数一数有几条时间序列

某服务暴露了指标 http_requests_total,带三个标签:

  • method:GET、POST、PUT、DELETE(4 种)
  • status:200、400、404、500(4 种)
  • instance:部署了 6 个实例

问:

  1. 理论上最多会产生多少条时间序列?
  2. 如果为了排查问题,再加一个 user_id 标签(日活 10 万用户),序列数会变成多少?这会带来什么后果?
🎯练习 4:选型题

以下三个场景,分别推荐 Prometheus / Zabbix / 商业 APM 中的哪一个(或组合),说明理由:

  1. 一家创业公司,8 人研发团队,全部服务跑在 K8s 上,没有专职运维。
  2. 一家传统制造企业的机房,有 200 台物理服务器、大量交换机和 UPS 设备,需要监控硬件温度、风扇转速、SNMP 网络流量。
  3. 一个金融系统,需要精确到每一笔交易的耗时明细,用于事后审计与客诉举证。

小结

  • Prometheus = 时序数据库 + 采集器 + 查询语言 + 告警引擎,专注 Metrics 这一支柱。
  • 监控数据「写多读少、只追加、按时间访问」,所以需要专门的 TSDB;Gorilla 压缩让每个样本只占 1–2 字节。
  • Pull 模型带来目标存活可观测、配置集中、易调试、不易被打垮;短任务和网络不可达是它的短板,用 Pushgateway 和 remote_write 补救。
  • 核心概念:时序 = 指标名 + 标签集合,样本 = (时间戳, float64 值)。
  • 甜点区是云原生动态环境;不要用它做计费、审计、日志检索和高基数分析。
  • 下一章我们拆开 Prometheus 的架构,看看 Server、Exporter、Alertmanager 各自在干什么 →