一、Prometheus 概念
Prometheus 是一个开源的系统监控 和告警工具包。Prometheus 将其指标作为时序数据进行收集和存储,即指标信息与记录的时间戳一起存储,同时还包含称为标签的可选键值对。
1. 特性
- 多维数据模型,通过指标名称和键/值对标识时序数据
- PromQL ,一种灵活的查询语言,可利用这种多维性
- 不依赖分布式存储;单个服务器节点是自治的
- 通过 HTTP 的**拉取(pull)**模型进行时序数据收集
- 支持通过中间网关推送(push)时序数据
- 通过服务发现或静态配置发现目标
- 支持多种图形和仪表盘模式
2. 什么是指标?
指标就是数值测量。时序:随时间变化的记录
用户想要测量的内容因应用程序而异。对于 Web 服务器,可能是请求时间;对于数据库,可能是活动连接数或活动查询数等等。
3. 架构
#mermaid-svg-5uxMIJkNR9ffFZej{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-5uxMIJkNR9ffFZej .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-5uxMIJkNR9ffFZej .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-5uxMIJkNR9ffFZej .error-icon{fill:#552222;}#mermaid-svg-5uxMIJkNR9ffFZej .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-5uxMIJkNR9ffFZej .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-5uxMIJkNR9ffFZej .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-5uxMIJkNR9ffFZej .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-5uxMIJkNR9ffFZej .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-5uxMIJkNR9ffFZej .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-5uxMIJkNR9ffFZej .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-5uxMIJkNR9ffFZej .marker{fill:#333333;stroke:#333333;}#mermaid-svg-5uxMIJkNR9ffFZej .marker.cross{stroke:#333333;}#mermaid-svg-5uxMIJkNR9ffFZej svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-5uxMIJkNR9ffFZej p{margin:0;}#mermaid-svg-5uxMIJkNR9ffFZej .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-5uxMIJkNR9ffFZej .cluster-label text{fill:#333;}#mermaid-svg-5uxMIJkNR9ffFZej .cluster-label span{color:#333;}#mermaid-svg-5uxMIJkNR9ffFZej .cluster-label span p{background-color:transparent;}#mermaid-svg-5uxMIJkNR9ffFZej .label text,#mermaid-svg-5uxMIJkNR9ffFZej span{fill:#333;color:#333;}#mermaid-svg-5uxMIJkNR9ffFZej .node rect,#mermaid-svg-5uxMIJkNR9ffFZej .node circle,#mermaid-svg-5uxMIJkNR9ffFZej .node ellipse,#mermaid-svg-5uxMIJkNR9ffFZej .node polygon,#mermaid-svg-5uxMIJkNR9ffFZej .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-5uxMIJkNR9ffFZej .rough-node .label text,#mermaid-svg-5uxMIJkNR9ffFZej .node .label text,#mermaid-svg-5uxMIJkNR9ffFZej .image-shape .label,#mermaid-svg-5uxMIJkNR9ffFZej .icon-shape .label{text-anchor:middle;}#mermaid-svg-5uxMIJkNR9ffFZej .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-5uxMIJkNR9ffFZej .rough-node .label,#mermaid-svg-5uxMIJkNR9ffFZej .node .label,#mermaid-svg-5uxMIJkNR9ffFZej .image-shape .label,#mermaid-svg-5uxMIJkNR9ffFZej .icon-shape .label{text-align:center;}#mermaid-svg-5uxMIJkNR9ffFZej .node.clickable{cursor:pointer;}#mermaid-svg-5uxMIJkNR9ffFZej .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-5uxMIJkNR9ffFZej .arrowheadPath{fill:#333333;}#mermaid-svg-5uxMIJkNR9ffFZej .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-5uxMIJkNR9ffFZej .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-5uxMIJkNR9ffFZej .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5uxMIJkNR9ffFZej .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-5uxMIJkNR9ffFZej .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5uxMIJkNR9ffFZej .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-5uxMIJkNR9ffFZej .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-5uxMIJkNR9ffFZej .cluster text{fill:#333;}#mermaid-svg-5uxMIJkNR9ffFZej .cluster span{color:#333;}#mermaid-svg-5uxMIJkNR9ffFZej div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-5uxMIJkNR9ffFZej .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-5uxMIJkNR9ffFZej rect.text{fill:none;stroke-width:0;}#mermaid-svg-5uxMIJkNR9ffFZej .icon-shape,#mermaid-svg-5uxMIJkNR9ffFZej .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5uxMIJkNR9ffFZej .icon-shape p,#mermaid-svg-5uxMIJkNR9ffFZej .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-5uxMIJkNR9ffFZej .icon-shape .label rect,#mermaid-svg-5uxMIJkNR9ffFZej .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5uxMIJkNR9ffFZej .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-5uxMIJkNR9ffFZej .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-5uxMIJkNR9ffFZej :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-5uxMIJkNR9ffFZej .collect>*{fill:#e3f2fd!important;stroke:#1e88e5!important;stroke-width:2px!important;}#mermaid-svg-5uxMIJkNR9ffFZej .collect span{fill:#e3f2fd!important;stroke:#1e88e5!important;stroke-width:2px!important;}#mermaid-svg-5uxMIJkNR9ffFZej .mem>*{fill:#fff8e1!important;stroke:#fbc02d!important;stroke-width:2px!important;}#mermaid-svg-5uxMIJkNR9ffFZej .mem span{fill:#fff8e1!important;stroke:#fbc02d!important;stroke-width:2px!important;}#mermaid-svg-5uxMIJkNR9ffFZej .crash>*{fill:#fce4ec!important;stroke:#d81b60!important;stroke-width:2px!important;stroke-dasharray:4 4!important;}#mermaid-svg-5uxMIJkNR9ffFZej .crash span{fill:#fce4ec!important;stroke:#d81b60!important;stroke-width:2px!important;stroke-dasharray:4 4!important;}#mermaid-svg-5uxMIJkNR9ffFZej .storage>*{fill:#f3e5f5!important;stroke:#8e24aa!important;stroke-width:2px!important;}#mermaid-svg-5uxMIJkNR9ffFZej .storage span{fill:#f3e5f5!important;stroke:#8e24aa!important;stroke-width:2px!important;} 重放
还原数据
📊 数据采集
Scrape Metrics
🧠 写入内存
Memory Block
(当前活动块)
📝 写入 WAL
Write-Ahead Log
(128MB 段文件)
🔄 系统崩溃恢复
WAL Replay
⏰ 2小时后触发
Block Compaction
💾 持久化到磁盘
2-hour Block
(chunks + index + metadata)
📦 后台压缩
Background Compaction
(合并为更大的块)
🏛️ 长期存储
Long-term Blocks
(最长31天或保留期10%)
1.
Prometheus Server
- Retrieval(抓取模块):定期通过 HTTP **pull(拉)**指标
- TSDB(时序数据库):存储监控数据
- HTTP Server:提供查询 API + Web UI
2.
Service Discovery
- 自动发现要监控谁
3.
Exporters / Jobs(数据来源)
- 各种 exporter(如 node_exporter、mysql_exporter)
- 业务服务自身暴露
/metrics4.
Pushgateway
给 短生命周期任务(Short-lived jobs) 用,比如批处理、定时任务(cron job)
流程:任务结束后把
指标push到Pushgateway,Prometheus 再去 pull Pushgateway
Pushgateway(让短任务也能被监控):job → Pushgateway → Prometheus pull。解决任务结束太快,抓不到指标(监控数据会推送到Pushgateway,保存在内存,等Prometheus 来 pull,然后保存TSDB)5.
Alertmanager(告警系统)
- 接收 Prometheus 发来的 alerts(做分组、去重、静默、路由)然后通知:PagerDuty、Email
- 核心:告警治理中心
Prometheus 定期拉各个服务的指标 → 存储 → 查询 → 触发告警 → Alertmanager 负责通知
Prometheus 从插桩任务抓取指标 ,或者通过中间推送网关抓取短期任务的指标。它在本地存储所有抓取的样本,并对这些数据运行规则,以便从现有数据聚合和记录新的时序数据,或者生成告警。可以使用 Grafana 或其他 API 消费者来可视化收集的数据。
使用场景
- 监控 数值型指标
- 微服务 / 云原生:k8s或微服务中服务可能很多,实例动态变化,Prometheus 自动发现服务、多维度标签(label)
- 故障排查:系统挂了也能看历史数据
- 报警系统
不适用
- 绝对精确的数据(Prometheus是采样+拉取模式(可能会丢数据))
- 计费系统(计费系统要求百分百精确)
- 日志 / 大文本 (只存数值,不存日志内容)
- 不适合长期大规模存储 (Prometheus 本地 TSDB、不适合存几年数据)
4. Prometheus 指标类型
- Counter:累积计数器 ,只能增加或重置为零,适合统计请求总数、错误次数等单调递增的指标。
- Gauge:仪表盘类型 ,数值可以任意上下波动,适合记录当前状态值,比如内存使用量、当前在线用户数、队列长度等。
- Histogram:直方图类型,用于观察数据分布情况,比如请求响应时间的分布。它会自动生成多个时间序列,包括各个桶的计数、总和以及总数,可以用来计算百分位数等统计指标。
- Summary:和 Histogram 类似,但它在客户端预先计算百分位数,适合需要精确百分位数计算但对网络传输有要求的场景。
5. 监控数据分类
- 系统指标(Infrastructure Metrics):CPU、内存、磁盘 I/O。属于底层物理状态。
- 应用指标(Application Metrics):QPS、响应时间(RT)、错误率。属于服务健康状态。
- 业务指标(Business Metrics):AI 调用次数、Token 消耗量、活跃用户数。属于钱和用户体验层面的数据。
- 调用链(Distributed Tracing):跨越多个服务、多个进程的请求轨迹。
调用链里的核心术语(Trace vs Span)
Trace(整条链路) :代表你从北京飞到巴黎的完整旅程。
Span(操作单元) :代表旅程中的具体单步操作。比如:
Span 1: 北京打车去机场。Span 2: 机场安检排队。Span 3: 飞机在空中飞行。
渲染错误: Mermaid 渲染失败: Invalid date:800ms) : 0
指标 (Prometheus):看系统是不是还活着(概览)。
日志 (ES + Kibana):看系统挂掉的那一刻打印了什么(细节)。
追踪 (Trace + Span):看请求卡在哪个微服务、哪个数据库查询上(定位瓶颈)。
6. 百分位数
- P50 :中位数。表示 50% 的请求响应时间都在这个值以下。
- P75:表示 75% 的请求响应时间都在这个值以下。
- P90:表示 90%的请求响应时间都在这个值以下。
- P99:表示 99% 的请求响应时间都在这个值以下。
例如:一个接口的 P99 响应时间是 500ms,这意味着 99%的请求都能在 500ms 内完成,只有 1% 的请求可能超过这个时间。
Prometheus 中,百分位数通常是通过 Histogram(直方图) 类型指标结合 histogram_quantile 函数计算出来的估算值:
bash
# 计算过去 5 分钟内,HTTP 请求耗时的 P99 (0.99)
histogram_quantile(
0.99,
sum by (le) (rate(http_request_duration_seconds_bucket[5m]))
)
7. 可观测性方法论
**1. 统计什么?**需要根据业务特点确定关键指标,既要覆盖 系统层面 的通用指标,也要包含 业务特有 的监控维度。
**2. 如何收集?**数据收集是可观测性的基础,可以通过代码埋点、探针技术、日志分析等多种方式实现。
**3. 如何存储?**监控数据通常量大且连续,需要选择合适的存储方案,比如时序数据库或专门的监控系统。
- 时序数据(指标):Prometheus TSDB。
- 文本数据(日志):Elasticsearch(ES)。
- 海量持久化(存储):Ceph。
**4. 如何展示?**最终需要通过直观的图表和仪表板将数据呈现给用户,一般会实时监控(页面自动刷新)。
- 大屏展示:Grafana(对接 Prometheus 数据源)。
- 日志检索:Kibana(对接 ES 数据源)。
二、常见术语
采集 → 存储 → 查询 → 告警
1. 数据核心
1.时间序列(Time Series) :指标名 + 标签集合(http_requests_total{method="GET",status="200"}),<metric name>{<label name>="<label value>", ...}
2.样本(Sample):时间序列中的一个点,某一时刻的值
3.标签(Label):用来区分数据维度的键值对,分组过滤
2. 数据怎么来的
1.Exporter :翻译器,把系统数据----->转换成Prometheus 格式
2.Client Library :埋点SDK,在代码里直接打指标,http_requests_total++,类似代码里打日志
3.Endpoint(抓取点):一个Http地址:http://ip:port/metrics,Prometheus 就是访问这里拿数据
4.Target(目标): Prometheus 要抓的一个具体对象
5.Job(任务):一组 target 的集合,job = 一类服务
6.Instance(实例): job中的单机器,通常是一个进程
3.告警体系
1.Alert(告警): Prometheus 根据规则触发,例如CPU > 80%
2.Alertmanager :告警调度中心,功能分组、去重、路由、静默
3.Notification(通知):最终发出去的消息
4.Silence(静默):临时屏蔽告警,告警仍存在,但不发送通知
在 Prometheus 中,instance 表示一个具体的抓取目标(通常是一个进程),job 是一组具有相同功能的 instance。Prometheus 在抓取时会自动为所有时间序列添加 job 和 instance 标签,用于标识数据来源。同时,每次抓取还会生成如 up、scrape_duration_seconds 等内部指标,用于监控抓取本身的健康状态。最终数据:metric_name{job=..., instance=..., 其他标签...}
三、配置文件结构
| 文件 | 作用 |
|---|---|
| prometheus.yml (采集层:去哪拿数据) | 抓谁(采集配置) |
| rules.yml (计算告警层:拿到数据后要干嘛) | 怎么算 / 怎么告警 |
Prometheus 的配置采用 YAML 格式,prometheus.yml
1.三个配置块
yaml
global:
scrape_interval: 15s #控制 Prometheus 抓取目标的频率
evaluation_interval: 15s #控制 Prometheus 评估规则的频率
rule_files:
# - "first.rules"
# - "second.rules"
scrape_configs: #控制 Prometheus 监控哪些资源
- job_name: prometheus #任务名
static_configs:
- targets: ['localhost:9090']
有三个配置块:global、rule_files 和 scrape_configs。
-
global块控制 Prometheus 服务器的全局配置 。scrape_interval,控制 Prometheus 抓取目标的频率。``evaluation_interval` 选项控制 Prometheus 评估规则的频率。Prometheus 使用规则来创建新的时间序列并生成告警。 -
rule_files块加载规则文件的位置 -
scrape_configs控制 Prometheus 监控哪些资源 。Prometheus 会通过 HTTP 端点公开自身的数据。期望监控指标:https://:9090/metrics。
bash
./prometheus --config.file=prometheus.yml #启动命令
#或者启动脚本
@echo off
REM 启动 Prometheus
prometheus.exe --config.file=prometheus.yml
REM 保持命令窗口打开,以查看输出
pause
node_exporter:采集服务器资源指标的工具,把操作系统的运行状态 → 转成 Prometheus 能读的数据
2.配置案例
prometheus.yaml
yaml
# ==========全局配置===============
global:
scrape_interval: 15s # 全局默认抓取间隔(Prometheus 每 15 秒去拉一次指标)
evaluation_interval: 15s # 告警规则评估间隔(每 15 秒计算一次告警表达式)
# 给所有时间序列自动添加的标签(用于区分不同 Prometheus 实例)
external_labels:
monitor: 'codelab-monitor'
# =========================
# 规则文件(告警 / 记录规则)
# =========================
rule_files:
- 'prometheus.rules.yml' # 定义告警规则(Alert)或记录规则(Recording Rule)
# =========抓取配置(核心)================
scrape_configs:
# -------------------------
# 1. 监控 Prometheus 自身
# -------------------------
- job_name: 'prometheus' # job 名称(服务分类)
scrape_interval: 5s # 覆盖全局配置:每 5 秒抓一次(更高频监控自己)
static_configs:
- targets: ['localhost:9090'] # Prometheus 自己的 metrics 地址
# 实际抓取:http://localhost:9090/metrics
# -------------------------
# 2. 监控节点 / 服务(你自定义的)
# -------------------------
- job_name: 'node' # 表示一类服务(比如 node_exporter / 应用)
scrape_interval: 5s # 每 5 秒抓取一次(比默认更频繁)
static_configs:
# ===== 第一组:生产环境 =====
- targets: ['localhost:8080', 'localhost:8081']
labels:
group: 'production' # 自定义标签:标识这是生产环境
# ===== 第二组:灰度 / 金丝雀环境 =====
- targets: ['localhost:8082']
labels:
group: 'canary' # 自定义标签:标识这是测试/灰度环境
```
prometheus.rules.yml
yaml
groups:
# 如果某个实例 up == 0 持续 1 分钟 → 触发告警
- name: example-alert
rules:
- alert: InstanceDown #告警名字
expr: up == 0 #PromQL 条件
for: 1m #持续多久才触发
labels: #附加消息,如严重级别
severity: critical
annotations: #告警描述
summary: "实例挂了"
description: "{{$labels.instance}} 已经 1 分钟不可访问"
#记录规则,生成派生时间序列
- name: example-record
rules:
- record: job:http_requests:rate5m
expr: rate(http_requests_total[5m])
- name: system-metrics
interval: 30s
rules:
# ===== Recording Rule =====
- record: instance:cpu_usage:rate5m
expr: |
100 - avg by(instance)(
rate(node_cpu_seconds_total{mode="idle"}[5m])
) * 100
# ===== Alert Rule =====
- alert: HighCPU
expr: instance:cpu_usage:rate5m > 80
for: 2m
labels:
severity: warning
annotations:
summary: "CPU 使用率过高"
description: "{{ $labels.instance }} CPU > 80%"
**规则可以热加载:**修改 rules.yml,不用重启 Prometheus,立即生效
bash
curl -X POST http://localhost:9090/-/reload
派生时间序列:根据现有的时间序列计算出的新指标
四、规则
Prometheus 支持两种类型的规则,可以进行配置并定期评估:记录规则 和告警规则
1. 记录规则(Recording Rule)
记录规则:给复杂 PromQL 起一个缓存后的新指标名(提前算好,存起来)
cpu.rules.yml
yaml
groups:
- name: cpu_rules
interval: 15s
rules:
- record: instance:cpu_usage:rate5m
expr: avg by (instance) (
rate(node_cpu_seconds_total{mode!="idle"}[5m])
)
record 推荐格式:
level:metric:operation级别:指标:操作 instance:cpu_usage:rate5m
prometheus.yml引入
yaml
rule_files:
- "rules/cpu.rules.yml"
重载
bash
curl -X POST http://localhost:9090/-/reload
查询
bash
instance:cpu_usage:rate5m #不用写复杂表达式,查询速度快
原理:每个时间间隔执行一次计算写入TSDB,最终变成一个普通指标,只要查普通指标
2. 告警规则(Alerting Rule)
告警规则:基于 Prometheus 表达式语言定义告警条件,并将触发告警的通知发送到外部服务
流程:
#mermaid-svg-0s7j7wyLWJ5Bk9QS{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-0s7j7wyLWJ5Bk9QS .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .error-icon{fill:#552222;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .marker{fill:#333333;stroke:#333333;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .marker.cross{stroke:#333333;}#mermaid-svg-0s7j7wyLWJ5Bk9QS svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-0s7j7wyLWJ5Bk9QS p{margin:0;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .cluster-label text{fill:#333;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .cluster-label span{color:#333;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .cluster-label span p{background-color:transparent;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .label text,#mermaid-svg-0s7j7wyLWJ5Bk9QS span{fill:#333;color:#333;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .node rect,#mermaid-svg-0s7j7wyLWJ5Bk9QS .node circle,#mermaid-svg-0s7j7wyLWJ5Bk9QS .node ellipse,#mermaid-svg-0s7j7wyLWJ5Bk9QS .node polygon,#mermaid-svg-0s7j7wyLWJ5Bk9QS .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .rough-node .label text,#mermaid-svg-0s7j7wyLWJ5Bk9QS .node .label text,#mermaid-svg-0s7j7wyLWJ5Bk9QS .image-shape .label,#mermaid-svg-0s7j7wyLWJ5Bk9QS .icon-shape .label{text-anchor:middle;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .rough-node .label,#mermaid-svg-0s7j7wyLWJ5Bk9QS .node .label,#mermaid-svg-0s7j7wyLWJ5Bk9QS .image-shape .label,#mermaid-svg-0s7j7wyLWJ5Bk9QS .icon-shape .label{text-align:center;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .node.clickable{cursor:pointer;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .arrowheadPath{fill:#333333;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-0s7j7wyLWJ5Bk9QS .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-0s7j7wyLWJ5Bk9QS .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-0s7j7wyLWJ5Bk9QS .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .cluster text{fill:#333;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .cluster span{color:#333;}#mermaid-svg-0s7j7wyLWJ5Bk9QS div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-0s7j7wyLWJ5Bk9QS rect.text{fill:none;stroke-width:0;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .icon-shape,#mermaid-svg-0s7j7wyLWJ5Bk9QS .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .icon-shape p,#mermaid-svg-0s7j7wyLWJ5Bk9QS .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .icon-shape .label rect,#mermaid-svg-0s7j7wyLWJ5Bk9QS .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-0s7j7wyLWJ5Bk9QS .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-0s7j7wyLWJ5Bk9QS :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .prom>*{fill:#e1f5fe!important;stroke:#01579b!important;stroke-width:2px!important;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .prom span{fill:#e1f5fe!important;stroke:#01579b!important;stroke-width:2px!important;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .am>*{fill:#fff8e1!important;stroke:#ff8f00!important;stroke-width:2px!important;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .am span{fill:#fff8e1!important;stroke:#ff8f00!important;stroke-width:2px!important;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .notify>*{fill:#e8f5e9!important;stroke:#1b5e20!important;stroke-width:2px!important;}#mermaid-svg-0s7j7wyLWJ5Bk9QS .notify span{fill:#e8f5e9!important;stroke:#1b5e20!important;stroke-width:2px!important;} Alertmanager 内部管道处理
- 查询数据
- 触发阈值
条件满足但小于 for 时间
满足时间持续达到 for - 发送告警 API
- 满足路由规则
- 钉钉
- Slack
- 邮件
时序数据库 TSDB
计算 PromQL Expr
状态评估
Pending 挂起
Firing 激活
Alertmanager - 抑制 Inhibit
- 静默 Silence
- 分组 Group
- 去重 Deduplicate
Webhook / 接收器
钉钉机器人
Slack Channel
SMTP 邮件
txt
Prometheus 计算 expr
↓
生成告警(pending / firing)
↓
发送给 Alertmanager
↓
分组 / 去重 / 抑制 / 静默
↓
发通知(钉钉 / Slack / 邮件)
案例
yaml
groups:
- name: app_alerts
rules:
- alert: HighCPUUsage
expr: avg by (pod) (
rate(container_cpu_usage_seconds_total{image!=""}[5m])
) > 0.8 #布尔值
for: 5m #必须连续5分钟都满足条件才报警 在触发前用
keep_firing_for: 5m #在恢复后用
labels:
severity: warning
annotations:
summary: "Pod CPU 过高"
description: "{{ $labels.pod }} CPU 超过 80%,当前值 {{ $value }}"
for控制报警要不要触发 ,告警必须要加for,避免误报
keep_firing_for告警恢复后,继续保持告警状态的时间,避免告警风暴
txt
原始指标 (node_cpu...)
↓
记录规则(预计算)
↓
新指标(pod:cpu_usage:rate5m)
↓
告警规则(判断)
↓
Alertmanager(通知)
记录规则:算结果出来
告警规则:从结果中挑需要的出来
五、Agent Mode
Prometheus Agent :只负责 采集 + 转发 的轻量版 Prometheus, Agent Mode :采集器(collector)
| 功能 | 普通 Prometheus | Agent Mode |
|---|---|---|
| 抓取(scrape) | ✅ | ✅ |
| 本地存储(TSDB) | ✅ | ❌(只有临时 WAL) |
| 查询(PromQL) | ✅ | ❌ |
| 记录规则 | ✅ | ❌ |
| 告警规则 | ✅ | ❌ |
| Remote Write | ✅ | ✅(核心功能) |

解决的问题
传统普罗米修斯的问题,大规模环境(比如 Kubernetes 多集群):每个节点都跑完整 Prometheus → 太重,数据分散 → 没有全局视图,运维复杂
1. Agent Mode 的思路
#mermaid-svg-RlRkReUkD05V8ICk{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-RlRkReUkD05V8ICk .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-RlRkReUkD05V8ICk .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-RlRkReUkD05V8ICk .error-icon{fill:#552222;}#mermaid-svg-RlRkReUkD05V8ICk .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-RlRkReUkD05V8ICk .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-RlRkReUkD05V8ICk .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-RlRkReUkD05V8ICk .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-RlRkReUkD05V8ICk .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-RlRkReUkD05V8ICk .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-RlRkReUkD05V8ICk .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-RlRkReUkD05V8ICk .marker{fill:#333333;stroke:#333333;}#mermaid-svg-RlRkReUkD05V8ICk .marker.cross{stroke:#333333;}#mermaid-svg-RlRkReUkD05V8ICk svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-RlRkReUkD05V8ICk p{margin:0;}#mermaid-svg-RlRkReUkD05V8ICk .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-RlRkReUkD05V8ICk .cluster-label text{fill:#333;}#mermaid-svg-RlRkReUkD05V8ICk .cluster-label span{color:#333;}#mermaid-svg-RlRkReUkD05V8ICk .cluster-label span p{background-color:transparent;}#mermaid-svg-RlRkReUkD05V8ICk .label text,#mermaid-svg-RlRkReUkD05V8ICk span{fill:#333;color:#333;}#mermaid-svg-RlRkReUkD05V8ICk .node rect,#mermaid-svg-RlRkReUkD05V8ICk .node circle,#mermaid-svg-RlRkReUkD05V8ICk .node ellipse,#mermaid-svg-RlRkReUkD05V8ICk .node polygon,#mermaid-svg-RlRkReUkD05V8ICk .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-RlRkReUkD05V8ICk .rough-node .label text,#mermaid-svg-RlRkReUkD05V8ICk .node .label text,#mermaid-svg-RlRkReUkD05V8ICk .image-shape .label,#mermaid-svg-RlRkReUkD05V8ICk .icon-shape .label{text-anchor:middle;}#mermaid-svg-RlRkReUkD05V8ICk .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-RlRkReUkD05V8ICk .rough-node .label,#mermaid-svg-RlRkReUkD05V8ICk .node .label,#mermaid-svg-RlRkReUkD05V8ICk .image-shape .label,#mermaid-svg-RlRkReUkD05V8ICk .icon-shape .label{text-align:center;}#mermaid-svg-RlRkReUkD05V8ICk .node.clickable{cursor:pointer;}#mermaid-svg-RlRkReUkD05V8ICk .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-RlRkReUkD05V8ICk .arrowheadPath{fill:#333333;}#mermaid-svg-RlRkReUkD05V8ICk .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-RlRkReUkD05V8ICk .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-RlRkReUkD05V8ICk .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-RlRkReUkD05V8ICk .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-RlRkReUkD05V8ICk .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-RlRkReUkD05V8ICk .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-RlRkReUkD05V8ICk .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-RlRkReUkD05V8ICk .cluster text{fill:#333;}#mermaid-svg-RlRkReUkD05V8ICk .cluster span{color:#333;}#mermaid-svg-RlRkReUkD05V8ICk div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-RlRkReUkD05V8ICk .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-RlRkReUkD05V8ICk rect.text{fill:none;stroke-width:0;}#mermaid-svg-RlRkReUkD05V8ICk .icon-shape,#mermaid-svg-RlRkReUkD05V8ICk .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-RlRkReUkD05V8ICk .icon-shape p,#mermaid-svg-RlRkReUkD05V8ICk .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-RlRkReUkD05V8ICk .icon-shape .label rect,#mermaid-svg-RlRkReUkD05V8ICk .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-RlRkReUkD05V8ICk .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-RlRkReUkD05V8ICk .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-RlRkReUkD05V8ICk :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-RlRkReUkD05V8ICk .edge>*{fill:#e1f5fe!important;stroke:#01579b!important;stroke-width:2px!important;}#mermaid-svg-RlRkReUkD05V8ICk .edge span{fill:#e1f5fe!important;stroke:#01579b!important;stroke-width:2px!important;}#mermaid-svg-RlRkReUkD05V8ICk .center>*{fill:#e8f5e9!important;stroke:#1b5e20!important;stroke-width:2px!important;}#mermaid-svg-RlRkReUkD05V8ICk .center span{fill:#e8f5e9!important;stroke:#1b5e20!important;stroke-width:2px!important;}#mermaid-svg-RlRkReUkD05V8ICk .ui>*{fill:#fff8e1!important;stroke:#ff8f00!important;stroke-width:2px!important;}#mermaid-svg-RlRkReUkD05V8ICk .ui span{fill:#fff8e1!important;stroke:#ff8f00!important;stroke-width:2px!important;} 统一观测与告警
监控中心 / 中央存储
边缘/各 K8s 节点集群
Remote Write
历史冷数据
PromQL 查询
评估规则
飞书/邮件/微信
应用 A /metrics
Prometheus Agent
应用 B /metrics
WAL 本地盘
中央网关/分发器
时序数据库 Mimir/Thanos/Cortex
对象存储 S3/MinIO
Grafana 面板
Alertmanager 告警
运维人员
txt
每个节点:Prometheus Agent(只采集)
↓
Remote Write
↓
中心:Prometheus / Thanos / Cortex / Mimir
↓
统一查询 + 告警
边缘采集 + 中心分析
工作流程
#mermaid-svg-5FjOOUW5RtcxQ5gW{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-5FjOOUW5RtcxQ5gW .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-5FjOOUW5RtcxQ5gW .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-5FjOOUW5RtcxQ5gW .error-icon{fill:#552222;}#mermaid-svg-5FjOOUW5RtcxQ5gW .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-5FjOOUW5RtcxQ5gW .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-5FjOOUW5RtcxQ5gW .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-5FjOOUW5RtcxQ5gW .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-5FjOOUW5RtcxQ5gW .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-5FjOOUW5RtcxQ5gW .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-5FjOOUW5RtcxQ5gW .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-5FjOOUW5RtcxQ5gW .marker{fill:#333333;stroke:#333333;}#mermaid-svg-5FjOOUW5RtcxQ5gW .marker.cross{stroke:#333333;}#mermaid-svg-5FjOOUW5RtcxQ5gW svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-5FjOOUW5RtcxQ5gW p{margin:0;}#mermaid-svg-5FjOOUW5RtcxQ5gW .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-5FjOOUW5RtcxQ5gW .cluster-label text{fill:#333;}#mermaid-svg-5FjOOUW5RtcxQ5gW .cluster-label span{color:#333;}#mermaid-svg-5FjOOUW5RtcxQ5gW .cluster-label span p{background-color:transparent;}#mermaid-svg-5FjOOUW5RtcxQ5gW .label text,#mermaid-svg-5FjOOUW5RtcxQ5gW span{fill:#333;color:#333;}#mermaid-svg-5FjOOUW5RtcxQ5gW .node rect,#mermaid-svg-5FjOOUW5RtcxQ5gW .node circle,#mermaid-svg-5FjOOUW5RtcxQ5gW .node ellipse,#mermaid-svg-5FjOOUW5RtcxQ5gW .node polygon,#mermaid-svg-5FjOOUW5RtcxQ5gW .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-5FjOOUW5RtcxQ5gW .rough-node .label text,#mermaid-svg-5FjOOUW5RtcxQ5gW .node .label text,#mermaid-svg-5FjOOUW5RtcxQ5gW .image-shape .label,#mermaid-svg-5FjOOUW5RtcxQ5gW .icon-shape .label{text-anchor:middle;}#mermaid-svg-5FjOOUW5RtcxQ5gW .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-5FjOOUW5RtcxQ5gW .rough-node .label,#mermaid-svg-5FjOOUW5RtcxQ5gW .node .label,#mermaid-svg-5FjOOUW5RtcxQ5gW .image-shape .label,#mermaid-svg-5FjOOUW5RtcxQ5gW .icon-shape .label{text-align:center;}#mermaid-svg-5FjOOUW5RtcxQ5gW .node.clickable{cursor:pointer;}#mermaid-svg-5FjOOUW5RtcxQ5gW .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-5FjOOUW5RtcxQ5gW .arrowheadPath{fill:#333333;}#mermaid-svg-5FjOOUW5RtcxQ5gW .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-5FjOOUW5RtcxQ5gW .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-5FjOOUW5RtcxQ5gW .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5FjOOUW5RtcxQ5gW .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-5FjOOUW5RtcxQ5gW .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5FjOOUW5RtcxQ5gW .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-5FjOOUW5RtcxQ5gW .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-5FjOOUW5RtcxQ5gW .cluster text{fill:#333;}#mermaid-svg-5FjOOUW5RtcxQ5gW .cluster span{color:#333;}#mermaid-svg-5FjOOUW5RtcxQ5gW div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-5FjOOUW5RtcxQ5gW .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-5FjOOUW5RtcxQ5gW rect.text{fill:none;stroke-width:0;}#mermaid-svg-5FjOOUW5RtcxQ5gW .icon-shape,#mermaid-svg-5FjOOUW5RtcxQ5gW .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5FjOOUW5RtcxQ5gW .icon-shape p,#mermaid-svg-5FjOOUW5RtcxQ5gW .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-5FjOOUW5RtcxQ5gW .icon-shape .label rect,#mermaid-svg-5FjOOUW5RtcxQ5gW .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5FjOOUW5RtcxQ5gW .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-5FjOOUW5RtcxQ5gW .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-5FjOOUW5RtcxQ5gW :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-5FjOOUW5RtcxQ5gW .app>*{fill:#f9f!important;stroke:#333!important;stroke-width:2px!important;}#mermaid-svg-5FjOOUW5RtcxQ5gW .app span{fill:#f9f!important;stroke:#333!important;stroke-width:2px!important;}#mermaid-svg-5FjOOUW5RtcxQ5gW .agent>*{fill:#bbf!important;stroke:#333!important;stroke-width:2px!important;stroke-dasharray:5 5!important;}#mermaid-svg-5FjOOUW5RtcxQ5gW .agent span{fill:#bbf!important;stroke:#333!important;stroke-width:2px!important;stroke-dasharray:5 5!important;}#mermaid-svg-5FjOOUW5RtcxQ5gW .storage>*{fill:#dfd!important;stroke:#333!important;stroke-width:2px!important;}#mermaid-svg-5FjOOUW5RtcxQ5gW .storage span{fill:#dfd!important;stroke:#333!important;stroke-width:2px!important;} 监控远端存储中心
Kubernetes 集群 / 边缘节点
- 暂存
- 重放
历史归档
暴露指标
Pull 拉取 - Remote Write 推送
应用服务
HTTP /metrics
Prometheus Agent
WAL 本地缓存
接收器/分发器
时序数据库 Mimir/Thanos
对象存储 S3/OSS
tex
应用 → /metrics
↓
Prometheus Agent(pull)
↓
WAL(短暂缓存)
↓
Remote Write(push)
↓
远端存储(Prometheus / Thanos / Mimir)
2. 核心优势
- 资源占用极低
- 水平扩展能力强(要扩容加 Agent 就行)
- 解耦架构:采集层(Agent) ≠ 存储层(Remote)
- 支持全局监控( 所有数据汇总到一个中心)
缺点
- 不能本地查询(本地不能执行PromQL)
- 不能写记录规则( 必须放到远端系统)
- 不能告警( Agent 不会发任何告警)
3. 启动Agent
Agent 模式 : 只负责采集 + 转发,不负责存储和计算
bash
prometheus --config.file=prometheus.yml --agent
#===========或===========================
prometheus \
--config.file=prometheus.yml \
--agent \
--storage.agent.path=data-agent/ #本地缓存目录,临时存储,用于远程写remote_write
启动一个 Prometheus Agent,只负责采集指标,并通过 remote_write 转发,
data-agent/用来做临时缓存(WAL),不做长期存储。只有两小时缓存时间WAL是预写日志,防止系统崩了,内存中的数据也没了
4. 实验
本地采集 node metrics,直接推到中心 Prometheus
Node Exporter → Agent → remote_write → 中央存储
Agent(采集) → 中心 Prometheus(规则 + 告警)
#mermaid-svg-H5tOd6vB3mPemTxU{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-H5tOd6vB3mPemTxU .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-H5tOd6vB3mPemTxU .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-H5tOd6vB3mPemTxU .error-icon{fill:#552222;}#mermaid-svg-H5tOd6vB3mPemTxU .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-H5tOd6vB3mPemTxU .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-H5tOd6vB3mPemTxU .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-H5tOd6vB3mPemTxU .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-H5tOd6vB3mPemTxU .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-H5tOd6vB3mPemTxU .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-H5tOd6vB3mPemTxU .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-H5tOd6vB3mPemTxU .marker{fill:#333333;stroke:#333333;}#mermaid-svg-H5tOd6vB3mPemTxU .marker.cross{stroke:#333333;}#mermaid-svg-H5tOd6vB3mPemTxU svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-H5tOd6vB3mPemTxU p{margin:0;}#mermaid-svg-H5tOd6vB3mPemTxU .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-H5tOd6vB3mPemTxU .cluster-label text{fill:#333;}#mermaid-svg-H5tOd6vB3mPemTxU .cluster-label span{color:#333;}#mermaid-svg-H5tOd6vB3mPemTxU .cluster-label span p{background-color:transparent;}#mermaid-svg-H5tOd6vB3mPemTxU .label text,#mermaid-svg-H5tOd6vB3mPemTxU span{fill:#333;color:#333;}#mermaid-svg-H5tOd6vB3mPemTxU .node rect,#mermaid-svg-H5tOd6vB3mPemTxU .node circle,#mermaid-svg-H5tOd6vB3mPemTxU .node ellipse,#mermaid-svg-H5tOd6vB3mPemTxU .node polygon,#mermaid-svg-H5tOd6vB3mPemTxU .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-H5tOd6vB3mPemTxU .rough-node .label text,#mermaid-svg-H5tOd6vB3mPemTxU .node .label text,#mermaid-svg-H5tOd6vB3mPemTxU .image-shape .label,#mermaid-svg-H5tOd6vB3mPemTxU .icon-shape .label{text-anchor:middle;}#mermaid-svg-H5tOd6vB3mPemTxU .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-H5tOd6vB3mPemTxU .rough-node .label,#mermaid-svg-H5tOd6vB3mPemTxU .node .label,#mermaid-svg-H5tOd6vB3mPemTxU .image-shape .label,#mermaid-svg-H5tOd6vB3mPemTxU .icon-shape .label{text-align:center;}#mermaid-svg-H5tOd6vB3mPemTxU .node.clickable{cursor:pointer;}#mermaid-svg-H5tOd6vB3mPemTxU .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-H5tOd6vB3mPemTxU .arrowheadPath{fill:#333333;}#mermaid-svg-H5tOd6vB3mPemTxU .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-H5tOd6vB3mPemTxU .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-H5tOd6vB3mPemTxU .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-H5tOd6vB3mPemTxU .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-H5tOd6vB3mPemTxU .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-H5tOd6vB3mPemTxU .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-H5tOd6vB3mPemTxU .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-H5tOd6vB3mPemTxU .cluster text{fill:#333;}#mermaid-svg-H5tOd6vB3mPemTxU .cluster span{color:#333;}#mermaid-svg-H5tOd6vB3mPemTxU div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-H5tOd6vB3mPemTxU .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-H5tOd6vB3mPemTxU rect.text{fill:none;stroke-width:0;}#mermaid-svg-H5tOd6vB3mPemTxU .icon-shape,#mermaid-svg-H5tOd6vB3mPemTxU .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-H5tOd6vB3mPemTxU .icon-shape p,#mermaid-svg-H5tOd6vB3mPemTxU .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-H5tOd6vB3mPemTxU .icon-shape .label rect,#mermaid-svg-H5tOd6vB3mPemTxU .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-H5tOd6vB3mPemTxU .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-H5tOd6vB3mPemTxU .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-H5tOd6vB3mPemTxU :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-H5tOd6vB3mPemTxU .exporter>*{fill:#e8f5e9!important;stroke:#2e7d32!important;stroke-width:2px!important;}#mermaid-svg-H5tOd6vB3mPemTxU .exporter span{fill:#e8f5e9!important;stroke:#2e7d32!important;stroke-width:2px!important;}#mermaid-svg-H5tOd6vB3mPemTxU .agent>*{fill:#e1f5fe!important;stroke:#0288d1!important;stroke-width:2px!important;stroke-dasharray:5 5!important;}#mermaid-svg-H5tOd6vB3mPemTxU .agent span{fill:#e1f5fe!important;stroke:#0288d1!important;stroke-width:2px!important;stroke-dasharray:5 5!important;}#mermaid-svg-H5tOd6vB3mPemTxU .center>*{fill:#fff8e1!important;stroke:#f57c00!important;stroke-width:2px!important;}#mermaid-svg-H5tOd6vB3mPemTxU .center span{fill:#fff8e1!important;stroke:#f57c00!important;stroke-width:2px!important;}#mermaid-svg-H5tOd6vB3mPemTxU .storage>*{fill:#eceff1!important;stroke:#455a64!important;stroke-width:2px!important;}#mermaid-svg-H5tOd6vB3mPemTxU .storage span{fill:#eceff1!important;stroke:#455a64!important;stroke-width:2px!important;} 中心端 (监控数据中心)
边缘端 (Windows 本地环境)
暂存/重放
暴露指标
- HTTP Pull 拉取
- HTTP Post 远程推送
💻 Windows 物理机
OS 性能计数器
📊 windows_exporter
端口: 9182
🚀 Prometheus Agent
端口: 9091
💾 临时 WAL
data-agent/
📥 Remote Write 接收器
端口: 9090
🗄️ 中心 TSDB
data-center/
📈 Grafana 大屏
可视化展示
目录结构
bash
├── prometheus.exe # 主程序
├── prometheus-agent.yml # 边缘 Agent 配置文件
├── prometheus-center.yml # 中心 Server 配置文件
├── data-agent/ # 边缘 WAL 缓存目录(自动生成)
└── data-center/ # 中心 TSDB 存储目录(自动生成)
边缘端配置文件:prometheus-agent.yml
yaml
global:
scrape_interval: 5s # 实验期间设置快一点,5秒抓一次
external_labels:
cluster: "windows-edge-01" # 标识数据来自你的 Windows 边缘端
scrape_configs:
- job_name: "agent-self"
static_configs:
- targets: ["localhost:9091"] # 抓取 Agent 自己
# 抓取本地 Windows 的硬件指标
- job_name: "windows-host-metrics"
static_configs:
- targets: ["localhost:9182"] # 对应 windows_exporter 的端口
remote_write:
- url: "http://localhost:9090/api/v1/write" # 推送到本地 9090 端口(中心端)
中心端配置文件:prometheus-center.yml
yaml
global:
scrape_interval: 15s
scrape_configs:
- job_name: "center-self"
static_configs:
- targets: ["localhost:9090"] # 抓取中心自己
启动三个服务
- 中心端必须带上
--web.enable-remote-write-receiver开启接收功能 - Agent 必须带上
--agent参数!且修改监听端口(默认是 9090 会冲突)
bash
# 启动中心 Prometheus(端口:9090)
prometheus.exe --config.file=prometheus-center.yml --storage.tsdb.path=data-center/ --web.enable-remote-write-receiver
#启动边缘 Agent(端口:9091)
prometheus.exe --config.file=prometheus-agent.yml --agent --storage.agent.path=data-agent/ --web.listen-address=":9091"
#读取 Windows 的性能计数器---->并转化为 Prometheus 看得懂的指标
windows_exporter.exe # 默认监听在 9182 端口
访问中心端的 UI 界面:http://localhost:9090 查询中输入up点击执行查看到两台数据
-
up{instance="localhost:9090", job="center-self"}(中心自己抓的)。 -
up{cluster="windows-edge-01", instance="localhost:9091", job="agent-self"}(Agent 抓取后通过 Remote Write 推送过来的!)
查询命令
bash
#查看 C 盘剩余空间百分比
windows_logical_disk_free_bytes{volume="C:"} / windows_logical_disk_size_bytes{volume="C:"} * 100
六、PromQL
PromQL: 从 时间序列数据库 里做计算的 SQL
1. 常用函数
官网查询:https://prometheus.io/docs/prometheus/latest/querying/functions/
rate(xxx[时间窗口]):在这个时间窗口内,指标平均每秒增长多少
rate :把 累计计数器 转换成 每秒变化速度
rate( [5m] ):计算 5 分钟内所有点,取平均斜率。适合告警,因为它平滑,不会因为秒级的毛刺误报。
irate( [5m] ):只取 5 分钟内最后两个点 计算瞬时斜率。适合 Dashboard 展示,能敏锐捕捉瞬间的流量尖峰。
| 函数 | 含义 |
|---|---|
rate() 只要 _total 结尾必用 |
平均每秒增长(最常用) |
irate() 看瞬时尖峰,不建议告警 |
瞬时速率 |
increase() |
一段时间内总增量 |
sum() |
求和(聚合整体指标) |
avg() |
平均值 |
max() / min() |
最大值 / 最小值 |
sum by() K8s 必备 |
按标签分组聚合 |
topk() |
取前 N(找最耗资源) |
histogram_quantile() |
计算 P95 / P99 延迟 |
avg_over_time() |
时间窗口平均(平滑数据) |
max_over_time() |
时间窗口最大值(抓峰值) |
absent() 告警神器 |
数据不存在(服务挂了) |
| 场景 | 用什么 |
|---|---|
| 计数器(_total) | rate() |
| 总量统计 | sum() |
| 分组(pod/node) | by() |
| 延迟分析 | histogram_quantile() |
| 平滑数据 | avg_over_time() |
| 找峰值 | max_over_time() |
| 服务消失 | absent() |
bash
rate(http_requests_total[5m]) #每秒多少请求
increase(http_requests_total[5m]) #5分钟内总共多少请求
2. 数据类型
| 类型 | 含义 | 示例 |
|---|---|---|
| Instant Vector(瞬时向量) | 某一时刻的数据 | http_requests_total |
| Range Vector (范围向量) | 一段时间的数据 | http_requests_total[5m] |
| Scalar(标量) | 单个数字,浮点值 | 5 |
| String | 字符串 | "abc" |
3. 查询
官网案例:https://prometheus.io/docs/prometheus/latest/querying/examples/
Instant Vector
bash
http_requests_total #查询所有 http_requests_total,返回"当前值"
http_requests_total{job="prometheus"} #带标签过滤
http_requests_total{env=~"prod|test"} #正则匹配
Range Vector
bash
http_requests_total[5m] #取过去 5 分钟的数据, 这个不能画图必须搭配rate
rate(http_requests_total[5m])
sum(rate(http_requests_total[5m])) #全局 QPS
avg by (instance) ( #按实例分组,先rate再聚合
rate(http_requests_total[5m])
)
increase(http_requests_total[5m]) #5分钟内增加了多少
sum by (job) (
rate(http_requests_total[5m])
)
其它常用
bash
http_requests_total offset 5m #看 5 分钟前的数据
rate(http_requests_total[5m]) #当前 vs 1小时前
/
rate(http_requests_total[5m] offset 1h)
http_requests_total @ 1609746000 #查历史某一刻
rate(http_requests_total[5m])[30m:] #在过去30分钟内,每个时间点都计算一次最近5分钟的请求速率
七、存储
Prometheus 本地存储 = WAL(防丢) + 内存 Head(当前数据) + Block(2小时文件块) + 后台压缩
数据流
bash
采集数据
↓
WAL(写前日志)
↓
Head(内存 + chunks_head)
↓(每2小时)
Block(磁盘文件)
↓(后台)
Compaction(合并大块)
====================================================
写入 → WAL(防丢)
→ Head(可查询)
→ Block(落盘)
→ Compaction(优化存储)
#mermaid-svg-3jErtQj2h4Fi7vXF{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-3jErtQj2h4Fi7vXF .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-3jErtQj2h4Fi7vXF .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-3jErtQj2h4Fi7vXF .error-icon{fill:#552222;}#mermaid-svg-3jErtQj2h4Fi7vXF .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-3jErtQj2h4Fi7vXF .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-3jErtQj2h4Fi7vXF .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-3jErtQj2h4Fi7vXF .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-3jErtQj2h4Fi7vXF .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-3jErtQj2h4Fi7vXF .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-3jErtQj2h4Fi7vXF .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-3jErtQj2h4Fi7vXF .marker{fill:#333333;stroke:#333333;}#mermaid-svg-3jErtQj2h4Fi7vXF .marker.cross{stroke:#333333;}#mermaid-svg-3jErtQj2h4Fi7vXF svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-3jErtQj2h4Fi7vXF p{margin:0;}#mermaid-svg-3jErtQj2h4Fi7vXF .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-3jErtQj2h4Fi7vXF .cluster-label text{fill:#333;}#mermaid-svg-3jErtQj2h4Fi7vXF .cluster-label span{color:#333;}#mermaid-svg-3jErtQj2h4Fi7vXF .cluster-label span p{background-color:transparent;}#mermaid-svg-3jErtQj2h4Fi7vXF .label text,#mermaid-svg-3jErtQj2h4Fi7vXF span{fill:#333;color:#333;}#mermaid-svg-3jErtQj2h4Fi7vXF .node rect,#mermaid-svg-3jErtQj2h4Fi7vXF .node circle,#mermaid-svg-3jErtQj2h4Fi7vXF .node ellipse,#mermaid-svg-3jErtQj2h4Fi7vXF .node polygon,#mermaid-svg-3jErtQj2h4Fi7vXF .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-3jErtQj2h4Fi7vXF .rough-node .label text,#mermaid-svg-3jErtQj2h4Fi7vXF .node .label text,#mermaid-svg-3jErtQj2h4Fi7vXF .image-shape .label,#mermaid-svg-3jErtQj2h4Fi7vXF .icon-shape .label{text-anchor:middle;}#mermaid-svg-3jErtQj2h4Fi7vXF .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-3jErtQj2h4Fi7vXF .rough-node .label,#mermaid-svg-3jErtQj2h4Fi7vXF .node .label,#mermaid-svg-3jErtQj2h4Fi7vXF .image-shape .label,#mermaid-svg-3jErtQj2h4Fi7vXF .icon-shape .label{text-align:center;}#mermaid-svg-3jErtQj2h4Fi7vXF .node.clickable{cursor:pointer;}#mermaid-svg-3jErtQj2h4Fi7vXF .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-3jErtQj2h4Fi7vXF .arrowheadPath{fill:#333333;}#mermaid-svg-3jErtQj2h4Fi7vXF .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-3jErtQj2h4Fi7vXF .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-3jErtQj2h4Fi7vXF .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-3jErtQj2h4Fi7vXF .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-3jErtQj2h4Fi7vXF .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-3jErtQj2h4Fi7vXF .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-3jErtQj2h4Fi7vXF .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-3jErtQj2h4Fi7vXF .cluster text{fill:#333;}#mermaid-svg-3jErtQj2h4Fi7vXF .cluster span{color:#333;}#mermaid-svg-3jErtQj2h4Fi7vXF div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-3jErtQj2h4Fi7vXF .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-3jErtQj2h4Fi7vXF rect.text{fill:none;stroke-width:0;}#mermaid-svg-3jErtQj2h4Fi7vXF .icon-shape,#mermaid-svg-3jErtQj2h4Fi7vXF .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-3jErtQj2h4Fi7vXF .icon-shape p,#mermaid-svg-3jErtQj2h4Fi7vXF .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-3jErtQj2h4Fi7vXF .icon-shape .label rect,#mermaid-svg-3jErtQj2h4Fi7vXF .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-3jErtQj2h4Fi7vXF .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-3jErtQj2h4Fi7vXF .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-3jErtQj2h4Fi7vXF :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-3jErtQj2h4Fi7vXF .memory>*{fill:#e1f5fe!important;stroke:#01579b!important;stroke-width:2px!important;}#mermaid-svg-3jErtQj2h4Fi7vXF .memory span{fill:#e1f5fe!important;stroke:#01579b!important;stroke-width:2px!important;}#mermaid-svg-3jErtQj2h4Fi7vXF .disk>*{fill:#e8f5e9!important;stroke:#1b5e20!important;stroke-width:2px!important;}#mermaid-svg-3jErtQj2h4Fi7vXF .disk span{fill:#e8f5e9!important;stroke:#1b5e20!important;stroke-width:2px!important;}#mermaid-svg-3jErtQj2h4Fi7vXF .action>*{fill:#fff!important;stroke:#333!important;stroke-width:1px!important;}#mermaid-svg-3jErtQj2h4Fi7vXF .action span{fill:#fff!important;stroke:#333!important;stroke-width:1px!important;} 磁盘持久化层
内存层
拉取
同步写入
每2小时 Cut
指标来源 Exporter
数据采集引擎
Head 内存块
chunks_head 样本
WAL 本地磁盘日志
Block 2小时块
Block 2小时块
Compaction 后台合并
合并后的 Big Block
1. 磁盘目录结构
bash
data/
├── 01ABC... # block(2小时数据)
│ ├── chunks/ # 真正的数据
│ ├── index # 索引(label → 数据)
│ ├── meta.json # 元数据
│ └── tombstones # 删除标记
│
├── wal/ # 写前日志(防崩溃)
├── chunks_head/ # 当前未落盘数据
2. 核心组件
2.1 WAL(Write-Ahead Log)
本质 :防止数据丢失
数据一来先写 WAL,每个文件默认 128MB,至少保留 3 个
作用:就算 Prometheus 崩了,也能恢复数据
2.2 Head(当前数据区)
特点:
-
在内存中(+ 磁盘映射 chunks_head)
-
保存 最近 2 小时的数据
这部分数据 还没变成 block
2.3 Block(核心存储单位)
每 2 小时生成一个 block:
tex
block/
├── chunks/ 时间序列数据(压缩后)
├── index 倒排索引
├── meta.json 时间范围等信息
一个 block: 一段时间的数据快照(默认 2 小时)
2.4 Compaction(压缩)
后台自动做:把多个 2h block 合并,变成更大的 block
最大:≤ 31天 或 retention(保留) 的 10%
3. 删除机制
Prometheus 删除数据时,不会立即删除数据,会写到 tombstones
tombstones = 删除标记
真正删除发生再下一次 compaction(压缩)
WAL:是你的草稿纸,随时记下灵感,怕忘了。
Head:是你的脑子,记着最近 2 小时发生的事,随时可以查。
2h Block:是一本小笔记本。
Compaction:是年底把这些小笔记本装订成合集。
31 天或 10% 限制:合集不能太厚,太厚了书架放不下(内存不够),过期了想撕掉其中一页也很难撕。
4. 数据保留策略
- 时间 :
--storage.tsdb.retention.time=15d默认15天 - 大小:
--storage.tsdb.retention.size=100GB超过就删旧数据
谁先触发用谁(时间 or 大小)
Prometheus 用 WAL 保证不丢数据,用内存缓存当前数据,每 2 小时切块落盘,再通过 compaction 合并,并按 retention 删除旧数据。
八、Federation
一个 Prometheus 去抓取另一个 Prometheus 的部分指标
Prometheus 暴露一个接口:
http://prometheus:9090/federate
专门用于被别的 Prometheus 抓
抓什么数据必须指定
bash
match[]={job="prometheus"}
match[]={__name__=~"job:.*"}
配置案例
yaml
scrape_configs:
- job_name: 'federate'
scrape_interval: 15s
honor_labels: true #保留源Prometheus的label,否则会被覆盖
metrics_path: '/federate' # 专用接口
params:
'match[]': #过滤规则,必须写,否则会拉全量数据
- '{job="prometheus"}'
- '{__name__=~"job:.*"}'
static_configs:
- targets:
- 'source-prometheus-1:9090'
- 只能拉当前值,当前时刻的样本值
- 不是远程存储
适用:多机房汇总、全局 dashboard
架构
#mermaid-svg-3ScDrLqd8iTQOTMD{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-3ScDrLqd8iTQOTMD .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-3ScDrLqd8iTQOTMD .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-3ScDrLqd8iTQOTMD .error-icon{fill:#552222;}#mermaid-svg-3ScDrLqd8iTQOTMD .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-3ScDrLqd8iTQOTMD .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-3ScDrLqd8iTQOTMD .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-3ScDrLqd8iTQOTMD .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-3ScDrLqd8iTQOTMD .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-3ScDrLqd8iTQOTMD .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-3ScDrLqd8iTQOTMD .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-3ScDrLqd8iTQOTMD .marker{fill:#333333;stroke:#333333;}#mermaid-svg-3ScDrLqd8iTQOTMD .marker.cross{stroke:#333333;}#mermaid-svg-3ScDrLqd8iTQOTMD svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-3ScDrLqd8iTQOTMD p{margin:0;}#mermaid-svg-3ScDrLqd8iTQOTMD .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-3ScDrLqd8iTQOTMD .cluster-label text{fill:#333;}#mermaid-svg-3ScDrLqd8iTQOTMD .cluster-label span{color:#333;}#mermaid-svg-3ScDrLqd8iTQOTMD .cluster-label span p{background-color:transparent;}#mermaid-svg-3ScDrLqd8iTQOTMD .label text,#mermaid-svg-3ScDrLqd8iTQOTMD span{fill:#333;color:#333;}#mermaid-svg-3ScDrLqd8iTQOTMD .node rect,#mermaid-svg-3ScDrLqd8iTQOTMD .node circle,#mermaid-svg-3ScDrLqd8iTQOTMD .node ellipse,#mermaid-svg-3ScDrLqd8iTQOTMD .node polygon,#mermaid-svg-3ScDrLqd8iTQOTMD .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-3ScDrLqd8iTQOTMD .rough-node .label text,#mermaid-svg-3ScDrLqd8iTQOTMD .node .label text,#mermaid-svg-3ScDrLqd8iTQOTMD .image-shape .label,#mermaid-svg-3ScDrLqd8iTQOTMD .icon-shape .label{text-anchor:middle;}#mermaid-svg-3ScDrLqd8iTQOTMD .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-3ScDrLqd8iTQOTMD .rough-node .label,#mermaid-svg-3ScDrLqd8iTQOTMD .node .label,#mermaid-svg-3ScDrLqd8iTQOTMD .image-shape .label,#mermaid-svg-3ScDrLqd8iTQOTMD .icon-shape .label{text-align:center;}#mermaid-svg-3ScDrLqd8iTQOTMD .node.clickable{cursor:pointer;}#mermaid-svg-3ScDrLqd8iTQOTMD .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-3ScDrLqd8iTQOTMD .arrowheadPath{fill:#333333;}#mermaid-svg-3ScDrLqd8iTQOTMD .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-3ScDrLqd8iTQOTMD .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-3ScDrLqd8iTQOTMD .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-3ScDrLqd8iTQOTMD .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-3ScDrLqd8iTQOTMD .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-3ScDrLqd8iTQOTMD .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-3ScDrLqd8iTQOTMD .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-3ScDrLqd8iTQOTMD .cluster text{fill:#333;}#mermaid-svg-3ScDrLqd8iTQOTMD .cluster span{color:#333;}#mermaid-svg-3ScDrLqd8iTQOTMD div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-3ScDrLqd8iTQOTMD .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-3ScDrLqd8iTQOTMD rect.text{fill:none;stroke-width:0;}#mermaid-svg-3ScDrLqd8iTQOTMD .icon-shape,#mermaid-svg-3ScDrLqd8iTQOTMD .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-3ScDrLqd8iTQOTMD .icon-shape p,#mermaid-svg-3ScDrLqd8iTQOTMD .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-3ScDrLqd8iTQOTMD .icon-shape .label rect,#mermaid-svg-3ScDrLqd8iTQOTMD .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-3ScDrLqd8iTQOTMD .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-3ScDrLqd8iTQOTMD .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-3ScDrLqd8iTQOTMD :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 查询 / 聚合层
存储层
边缘层 / 数据采集
Agent
App Metrics
Prometheus Local
remote_write
Thanos / Long-term Storage
Federation /federate
Global Prometheus
Grafana / Alertmanager
例如
tx
北京机房 Prometheus
上海机房 Prometheus
深圳机房 Prometheus
↓
Federation
↓
Global Prometheus
Global 只关心:总QPS = 30000,不关心每台机器
九、Pushgateway
1.原理
Pushgateway :把短生命周期任务的指标,临时存起来,等 Prometheus 来拉
Prometheus 默认是Pull 模型(拉模式)。Prometheus → 主动去抓 exporter。特点:服务必须长期存活
有些任务运行几秒就退出了,Prometheus 来不及抓,任务就结束了
Pushgateway 解决方案:任务 → Pushgateway(存起来) → Prometheus(再来拉)
只是一个临时的指标缓存仓库 ,存储的不是历史数据,而是某一时刻的最后值,短任务的最后值缓存器
Pushgateway 内部是:
job + instance + metric → 内存存储
类似:
backup_job + server1 → task_duration_seconds = 3.5
Pushgateway存储的数据不会自动消失,它不会过期和自动清理,需要手动删除
由于短任务结束后,Pushgateway 会一直保留最后一次的值。如果任务失败了不再上报,Prometheus 依然会拉到旧值,导致误报。
解决方案:在脚本任务结束时,主动调用 API 删除它:
bash# 任务完成后,删除这个 Job 的数据 curl -X DELETE http://localhost:9091/metrics/job/backup_job
数据流
#mermaid-svg-kApBeSZwySAetpSt{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-kApBeSZwySAetpSt .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-kApBeSZwySAetpSt .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-kApBeSZwySAetpSt .error-icon{fill:#552222;}#mermaid-svg-kApBeSZwySAetpSt .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-kApBeSZwySAetpSt .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-kApBeSZwySAetpSt .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-kApBeSZwySAetpSt .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-kApBeSZwySAetpSt .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-kApBeSZwySAetpSt .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-kApBeSZwySAetpSt .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-kApBeSZwySAetpSt .marker{fill:#333333;stroke:#333333;}#mermaid-svg-kApBeSZwySAetpSt .marker.cross{stroke:#333333;}#mermaid-svg-kApBeSZwySAetpSt svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-kApBeSZwySAetpSt p{margin:0;}#mermaid-svg-kApBeSZwySAetpSt .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-kApBeSZwySAetpSt .cluster-label text{fill:#333;}#mermaid-svg-kApBeSZwySAetpSt .cluster-label span{color:#333;}#mermaid-svg-kApBeSZwySAetpSt .cluster-label span p{background-color:transparent;}#mermaid-svg-kApBeSZwySAetpSt .label text,#mermaid-svg-kApBeSZwySAetpSt span{fill:#333;color:#333;}#mermaid-svg-kApBeSZwySAetpSt .node rect,#mermaid-svg-kApBeSZwySAetpSt .node circle,#mermaid-svg-kApBeSZwySAetpSt .node ellipse,#mermaid-svg-kApBeSZwySAetpSt .node polygon,#mermaid-svg-kApBeSZwySAetpSt .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-kApBeSZwySAetpSt .rough-node .label text,#mermaid-svg-kApBeSZwySAetpSt .node .label text,#mermaid-svg-kApBeSZwySAetpSt .image-shape .label,#mermaid-svg-kApBeSZwySAetpSt .icon-shape .label{text-anchor:middle;}#mermaid-svg-kApBeSZwySAetpSt .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-kApBeSZwySAetpSt .rough-node .label,#mermaid-svg-kApBeSZwySAetpSt .node .label,#mermaid-svg-kApBeSZwySAetpSt .image-shape .label,#mermaid-svg-kApBeSZwySAetpSt .icon-shape .label{text-align:center;}#mermaid-svg-kApBeSZwySAetpSt .node.clickable{cursor:pointer;}#mermaid-svg-kApBeSZwySAetpSt .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-kApBeSZwySAetpSt .arrowheadPath{fill:#333333;}#mermaid-svg-kApBeSZwySAetpSt .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-kApBeSZwySAetpSt .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-kApBeSZwySAetpSt .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-kApBeSZwySAetpSt .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-kApBeSZwySAetpSt .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-kApBeSZwySAetpSt .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-kApBeSZwySAetpSt .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-kApBeSZwySAetpSt .cluster text{fill:#333;}#mermaid-svg-kApBeSZwySAetpSt .cluster span{color:#333;}#mermaid-svg-kApBeSZwySAetpSt div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-kApBeSZwySAetpSt .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-kApBeSZwySAetpSt rect.text{fill:none;stroke-width:0;}#mermaid-svg-kApBeSZwySAetpSt .icon-shape,#mermaid-svg-kApBeSZwySAetpSt .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-kApBeSZwySAetpSt .icon-shape p,#mermaid-svg-kApBeSZwySAetpSt .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-kApBeSZwySAetpSt .icon-shape .label rect,#mermaid-svg-kApBeSZwySAetpSt .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-kApBeSZwySAetpSt .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-kApBeSZwySAetpSt .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-kApBeSZwySAetpSt :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} push metrics
Prometheus scrape 定时拉取
PromQL 查询
脚本 / 批处理任务 / CronJob
Pushgateway
Prometheus TSDB
Grafana / Alertmanager
| 组件 | 模式 |
|---|---|
| 任务 → Pushgateway | Push |
| Prometheus → Pushgateway | Pull |
2.案例
脚本 → Pushgateway → Prometheus → Alert规则
启动: 运行 pushgateway.exe
在 prometheus.yml 加:
- job_name: pushgateway
static_configs:
- targets: ["localhost:9091"]
创建指标文件metrics.txt 写入,内容末尾有换行
tex
task_duration_seconds{type="backup"} 3.5
rules.yml添加 (文件编码要utf-8)
yaml
groups:
- name: pushgateway
rules:
- alert: JobFailed
expr: task_duration_seconds{job="backup_job"} > 8
for: 10s
labels:
severity: warning
annotations:
summary: "任务执行时间过长"
测试(push)
bash
C:\Users\linshengqian\Desktop\Monitoring>curl --data-binary @metrics.txt http://localhost:9091/metrics/job/backup_job
检查http://localhost:9091/metrics 指标中是否有task_duration_seconds
bash
task_duration_seconds{instance="",job="backup_job",type="backup"} 3.5
prometheus的PromQL查询
bash
task_duration_seconds