Prometheus 核心概念
一句话定义:
Prometheus 是一个以 时间序列 为核心、采用 Pull 模式、面向 云原生与大规模系统 的监控与告警系统。
它解决的是三个问题:
- 如何持续采集系统状态(Metrics)
- 如何高效存储和查询时间序列数据
- 如何用规则表达“异常”并触发告警
Prometheus 只关心 可聚合、可计算的数值指标:
- CPU 使用率
- 请求数
- 延迟
- 错误率
而不是:
- 文本日志
- 离散事件
👉 这是 Prometheus 能高性能运行的根本原因。
Prometheus 采用 Pull 模式:
Prometheus --> /metrics --> Target
设计动机:
- Prometheus 控制采集频率
- 自动发现服务
- 目标不需要知道 Prometheus 的存在
- 易于扩展、迁移
Push 只作为例外(Pushgateway)
Prometheus Server 本身是:
- 单节点
- 强一致
- 本地 TSDB
大规模问题交给:
- Thanos
- Cortex
- Mimir
- VictoriaMetrics
👉 Prometheus = 可靠内核 + 可扩展生态
Prometheus 中的一切都是 时间序列:
<metric_name>{<label_key>=<label_value>, ...}
每一个唯一的 (metric_name + labels) = 一条时间序列。
规范:
- 小写
- 下划线分隔
- 有单位后缀
示例:
- http_requests_total
- node_memory_MemAvailable_bytes
- request_duration_seconds
👉 指标名表达 “是什么”
标签用于 维度拆分与聚合:
http_requests_total{method="GET", status="200"}
👉 标签表达 “从哪个角度看”
⚠️ 标签决定数据规模(cardinality)
(timestamp, value)
- timestamp:毫秒级
- value:float64
基数 = 时间序列数量
series = metric_name × label 组合
例子:
http_requests_total
× method (3)
× status (5)
× path (1000)
= 15000 series
- 每条时间序列都需要:
- 内存
- WAL 写入
- 索引
- 内存占用随 series 数量线性增长
- 查询复杂度指数级上升
👉 OOM 的本质不是数据量,而是 series 数量
- ❌ user_id
- ❌ request_id
- ❌ session_id
- ❌ trace_id
- ❌ 动态 URL
Prometheus 有 4 种类型(语义约束):
| 类型 | 特性 | 场景 |
|---|---|---|
| Counter | 只增不减 | 请求数、错误数 |
| Gauge | 可增可减 | CPU、内存 |
| Histogram | bucket 统计 | 延迟、大小 |
| Summary | 客户端分位数 | 单实例延迟 |
Counter 永不减少:
- 重启 -> 从 0 开始(需 rate() 处理)
- 不能直接 avg(counter)
👉 所有流量类指标必须是 Counter。
| 维度 | Histogram | Summary |
|---|---|---|
| 分位数 | 服务端计算 | 客户端计算 |
| 跨实例聚合 | ✔ | ❌ |
| label 控制 | 好 | 差 |
| 推荐度 | ⭐⭐⭐⭐⭐ | ⭐ |
👉 生产统一用 Histogram
WAL -> Head -> Block(2h)
- WAL:防止数据丢失
- Head:内存中的当前数据
- Block:落盘后的压缩数据
- 控制压缩成本
- 提高查询效率
- 降低 compaction 复杂度
- 列式存储思想
- 倒排索引(label -> series)
- 内存 + mmap
- 顺序 IO
PromQL 是 面向时间序列的函数式查询语言。
核心操作:
- 选择时间序列
- 时间窗口计算
- 聚合
- 向量运算
| 类型 | 描述 |
|---|---|
| Instant Vector | 某一时刻的 series |
| Range Vector | 一段时间内的 samples |
| Scalar | 单一数值 |
| String | 标签文本 |
因为:
- Counter 是累计值
- 监控需要“变化率”
rate() = 对 Counter 做一阶导数。
告警 = PromQL + 时间约束
expr: CPU > 90%
for: 5m
含义:
连续 5 分钟 CPU > 90%,才算异常。
| 项 | 告警 | 图表 |
|---|---|---|
| 是否实时 | 是 | 否 |
| 是否容错 | 低 | 高 |
| 是否允许抖动 | 否 | 是 |
Prometheus 本身不做集群:
- 简化一致性
- 避免分布式复杂性
- 用冗余代替分布式
👉 “多实例 + 去重” ≠ “分布式数据库”
- Prometheus 监控的是“状态”,不是“事件”
- 时间序列数量决定一切
- 标签是最危险的设计点
- Pull 是可观测性的基础
- Prometheus 强在规则与生态,不在分布式