Prometheus+Grafana知识梳理(1)

作者:没有四次元口袋的蓝胖

日期:2026-09-30

标签:Prometheus, 监控体系


Prometheus+Grafana知识梳理(1)

监控系统是后端架构中不可或缺的一环。在微服务时代,没有监控就等于裸奔------服务挂了不知道、性能瓶颈找不到、容量规划靠猜。Prometheus 是目前最主流的开源监控方案,几乎所有中大型公司都在用,也是 Kubernetes 生态的标配监控组件。

这篇笔记聚焦 Prometheus 本身的架构设计与数据采集能力,从 Pull 模型的设计哲学到时序数据模型,再到 node_exporter 采集器的安装配置和常用 PromQL 指标,帮你建立扎实的基础认知。

核心掌握:Prometheus Pull模型与时序数据库、四大核心组件的职责分工、数据模型与四种指标类型、node_exporter采集与常用PromQL查询。


一、Prometheus核心架构

1.1 什么是Prometheus

Prometheus 是一个开源的系统监控和告警工具包,最初由 SoundCloud 于 2012 年开发,2016 年加入 CNCF(云原生计算基金会),是 Kubernetes 生态的标配监控组件。

核心特点:

  • 多维数据模型:基于 metric name + key/value labels 组织时序数据
  • Pull 模型:主动从目标拉取指标数据(也支持 Push 场景)
  • 服务发现:自动发现监控目标(K8s、Consul、DNS 等)
  • 强大的查询语言 PromQL:支持丰富的聚合、计算和过滤

1.2 Pull模型 vs Push模型

这是面试高频考点。Prometheus 的核心设计哲学是 Pull(拉取) 模型。

复制代码
┌─────────────┐         HTTP GET /metrics          ┌─────────────┐
│ Prometheus  │  ◄────────────────────────────────  │  目标服务    │
│   Server    │     定期拉取指标数据(默认15s)       │ (Exporter)  │
└─────────────┘                                     └─────────────┘

Pull模型的工作流程:
1. Prometheus Server 定时(scrape_interval)向目标发送 HTTP GET 请求
2. 目标暴露一个 /metrics 端点,返回纯文本格式的指标数据
3. Prometheus 解析并存储到时序数据库(TSDB)中

Pull vs Push 对比:

维度 Pull模型(Prometheus) Push模型(传统监控)
数据流向 监控中心主动拉取 被监控端主动推送
目标存活感知 拉不到 = 目标挂了,天然感知 需要额外心跳机制
配置管理 集中在监控端配置 分散在各业务端配置
网络要求 监控端需要能访问目标 目标需要能访问监控端
适用场景 基础设施监控、微服务 定时任务、批处理作业

为什么选 Pull 而不是 Push? 这个设计决策背后有几个关键思考:

  1. 天然存活感知:Pull 不到数据就意味着目标挂了,不需要额外的心跳机制。
  2. 配置集中:所有采集目标配置在 Prometheus Server 端管理,不用分散到各个业务服务。
  3. 便于调试 :开发者可以直接 curl http://target:port/metrics 查看原始指标,排查问题方便。
  4. 服务发现友好:配合 Consul、K8s 等服务发现机制,新实例上线自动纳入监控。

1.3 核心组件

Prometheus 生态由多个组件协作构成完整的监控体系:

复制代码
                        ┌──────────────────┐
                        │   Prometheus     │
                        │    Server        │◄── 拉取指标
                        │  (存储+查询+告警) │
                        └────────┬─────────┘
                                 │
                    ┌────────────┼────────────┐
                    │            │            │
              ┌─────▼─────┐ ┌──▼──────┐ ┌───▼────────┐
              │  TSDB     │ │Alertman │ │  Grafana   │
              │ (时序数据库)│ │  ager   │ │ (可视化)    │
              └───────────┘ └────┬────┘ └────────────┘
                                 │
                            ┌────▼────┐
                            │ 邮件/钉钉 │
                            │ /微信等  │
                            └─────────┘
组件 职责 说明
Prometheus Server 数据拉取、存储、查询 核心组件,包含 TSDB 和 PromQL 引擎
Exporter 暴露指标数据 各种类型的指标采集器(node_exporter、mysql_exporter 等)
Pushgateway 接收短生命周期任务的推送 定时任务等不适合 Pull 的场景
Alertmanager 告警处理与通知 去重、分组、静默、路由到不同通知渠道
Grafana 可视化展示 Dashboard 面板、数据探索

各组件的关系:

  • Prometheus Server 是整个体系的核心,负责定时从各 Exporter 拉取数据,存储到本地时序数据库(TSDB),同时支持 PromQL 查询引擎和告警规则评估。
  • Exporter 是各类指标采集器,它们暴露 HTTP /metrics 端点,等待 Prometheus 来拉取。
  • Pushgateway 是一个特殊组件,用于接收短生命周期任务(如 CronJob)主动推送的指标。这类任务可能在 Prometheus 来 Pull 之前就执行结束了,所以需要主动 Push。
  • Alertmanager 接收 Prometheus 评估告警规则后发来的告警,负责去重、分组、静默、抑制,最终路由到邮件/钉钉/微信等通知渠道。
  • Grafana 是纯可视化层,从 Prometheus 读取数据进行展示,本身不存储数据。

二、数据模型

2.1 时序数据格式

Prometheus 的数据模型非常简洁:每一条时序数据 = metric name + labels + timestamp + value。

复制代码
# 数据格式示例
http_requests_total{method="GET", handler="/api/users", status="200"} 1027
http_requests_total{method="POST", handler="/api/users", status="201"} 83

# 拆解:
# metric name: http_requests_total
# labels:      method="GET", handler="/api/users", status="200"
# timestamp:   (Prometheus自动添加)
# value:       1027
  • metric name :指标名称,描述"监控什么",如 http_requests_total、node_cpu_seconds_total。
  • labels :键值对标签,用于区分同一指标的不同维度,如 method="GET" 区分请求方法。
  • timestamp:Prometheus 自动添加的采集时间戳,不需要手动指定。
  • value:指标值,一个 64 位浮点数。

这种设计的好处是:通过 labels 的组合,可以在同一个指标下表达非常丰富的维度信息,查询时用 PromQL 按 labels 过滤和聚合。

2.2 四种核心指标类型

类型 说明 典型场景
Counter 只增不减的计数器 请求总数、错误总数
Gauge 可增可减的仪表盘 CPU使用率、内存使用量、队列长度
Histogram 直方图,预定义桶分布 请求延迟分布、响应大小分布
Summary 摘要,客户端计算分位数 请求延迟的 P99/P95
yaml 复制代码
# Counter示例:累计请求数(只能增加或重置为0)
http_requests_total{method="GET"} 5000

# Gauge示例:当前内存使用(可增可减)
node_memory_MemAvailable_bytes 8589934592

# Histogram示例:请求延迟分布
http_request_duration_seconds_bucket{le="0.1"} 2400
http_request_duration_seconds_bucket{le="0.5"} 4800
http_request_duration_seconds_bucket{le="1.0"} 4950
http_request_duration_seconds_bucket{le="+Inf"} 5000
http_request_duration_seconds_sum 1200.5
http_request_duration_seconds_count 5000

四种类型的选型建议:

  • Counter :任何"累计量"场景。注意 Counter 只能增加(除非进程重启归零),不能直接读值,需要用 rate() 计算增长率。
  • Gauge:任何"当前值"场景。如温度、内存使用量、队列长度等,可以直接读取当前值。
  • Histogram:需要知道分布的场景,如请求延迟。桶(bucket)的划分在服务端定义,多个实例的数据可以在 Prometheus Server 端聚合。
  • Summary:对单实例的分位数精度要求极高时使用。分位数在客户端计算,精度更高但无法跨实例聚合。

三、node_exporter采集与常用指标

3.1 什么是node_exporter

node_exporter 是 Prometheus 官方提供的硬件和操作系统指标采集器,用于采集 Linux/Unix 服务器的 CPU、内存、磁盘、网络等基础指标。它是监控体系中最基础的一环------先监控主机,再监控应用。

3.2 安装与配置

二进制安装(了解即可)
bash 复制代码
# 下载
wget https://github.com/prometheus/node_exporter/releases/download/v1.8.2/node_exporter-1.8.2.linux-amd64.tar.gz
tar xzvf node_exporter-1.8.2.linux-amd64.tar.gz
cd node_exporter-1.8.2.linux-amd64

# 启动(默认监听 9100 端口)
./node_exporter

# 验证:访问 http://localhost:9100/metrics 即可看到指标数据
Docker安装(推荐)
yaml 复制代码
# docker-compose.yml 片段
services:
  node_exporter:
    image: prom/node-exporter:latest
    container_name: node_exporter
    ports:
      - "9100:9100"
    # 关键:挂载宿主机文件系统,才能采集宿主机指标
    volumes:
      - /proc:/host/proc:ro
      - /sys:/host/sys:ro
      - /:/rootfs:ro
    command:
      - '--path.procfs=/host/proc'
      - '--path.sysfs=/host/sys'
      - '--path.rootfs=/rootfs'
      - '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|container)($$|/)'
    restart: unless-stopped

要点 :Docker 安装时,必须将宿主机的 /proc、/sys、/ 以只读方式挂载到容器内,并通过 --path.* 参数指定路径。否则 node_exporter 采集到的是容器自身的指标,而不是宿主机。

3.3 配置Prometheus采集

在 prometheus.yml 中添加采集任务(scrape job):

yaml 复制代码
global:
  scrape_interval: 15s          # 全局默认采集间隔

scrape_configs:
  # 采集 Prometheus 自身指标
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

  # 采集 node_exporter
  - job_name: 'node'
    static_configs:
      - targets: ['node_exporter:9100']   # Docker环境用容器名
        labels:
          env: 'production'               # 自定义标签
          instance: 'web-server-01'

3.4 常用指标速查

面试和实际工作中最高频的 PromQL 查询,按场景分类:

CPU相关
promql 复制代码
# CPU使用率(百分比)
100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)

# 各模式CPU时间占比
rate(node_cpu_seconds_total[5m])

# CPU核心数
count(node_cpu_seconds_total{mode="idle"}) by (instance)

解读 :CPU 使用率的核心思路是 100% - idle%。node_cpu_seconds_total 是 Counter 类型,记录了各模式(user、system、idle、iowait 等)下的 CPU 秒数。用 rate() 计算每秒增长率,取 mode="idle" 的空闲占比,再用 100 减去就是使用率。

内存相关
promql 复制代码
# 内存使用率
(1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100

# 可用内存
node_memory_MemAvailable_bytes

# 已用内存(不含buffer/cache)
node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes

# Swap使用率
(1 - node_memory_SwapFree_bytes / node_memory_SwapTotal_bytes) * 100

解读 :注意用 MemAvailable 而不是 MemFree。MemAvailable 包含了可回收的 buffer/cache 空间,更能反映实际可用内存。MemFree 只是完全空闲的内存,Linux 会把大量内存用于缓存,所以 MemFree 通常很小,直接用会导致误报。

磁盘相关
promql 复制代码
# 磁盘使用率
(1 - node_filesystem_avail_bytes{fstype!~"tmpfs|overlay"} / node_filesystem_size_bytes{fstype!~"tmpfs|overlay"}) * 100

# 磁盘IO速率(读)
rate(node_disk_read_bytes_total[5m])

# 磁盘IO速率(写)
rate(node_disk_written_bytes_total[5m])

# inode使用率
(1 - node_filesystem_files_free / node_filesystem_files) * 100

解读 :磁盘使用率用 avail 而不是 free。avail 包含可回收的空间(如 reserved for root),free 是完全空闲的。监控用 avail 更准确。fstype!~"tmpfs|overlay" 过滤掉临时文件系统,只关注真实磁盘。

网络相关
promql 复制代码
# 网络接收速率(bytes/s)
rate(node_network_receive_bytes_total{device!~"lo|veth.*|docker.*"}[5m])

# 网络发送速率(bytes/s)
rate(node_network_transmit_bytes_total{device!~"lo|veth.*|docker.*"}[5m])

# 网络错误率
rate(node_network_receive_errs_total[5m])

解读 :device!~"lo|veth.*|docker.*" 过滤掉 loopback、虚拟网卡和 Docker 网桥,只关注真实物理网卡。


四、PromQL关键函数速记

PromQL 是 Prometheus 的查询语言,以下是数据采集场景中最常用的函数:

函数 作用 适用类型 说明
rate() 每秒平均增长率 Counter 取时间窗口内所有点做线性回归,平滑
irate() 瞬时增长率 Counter 只取最后两个数据点,对突变更敏感
increase() 时间段内的增量 Counter 等价于 rate() * 时间窗口秒数
histogram_quantile() 分位数计算 Histogram 如 histogram_quantile(0.99, ...) 算 P99
avg by() / sum by() 聚合运算 通用 按指定 label 分组聚合

rate() vs irate():

  • irate() 只取最后两个数据点,对突变更敏感,适合实时面板展示。
  • rate() 取时间窗口内所有点做线性回归,更平滑,适合告警规则。
  • 告警用 rate(),实时面板可以用 irate()。

五、常见面试注意点

  • Pull模型的优势:天然感知目标存活、配置集中、易于调试(直接 curl /metrics 查看)。
  • Push模型的使用场景:短生命周期的批处理任务(如 CronJob),这类任务可能还没等到 Pull 就结束了,需要主动 Push 到 Pushgateway。
  • Counter vs Gauge :Counter 只能用 rate() / increase() 计算速率;Gauge 可以直接读取当前值。
  • Histogram vs Summary:Histogram 在服务端聚合,适合多实例;Summary 的分位数在客户端计算,无法跨实例聚合。

🗺️ 思维导图速览

复制代码
Prometheus 架构与数据采集
├── Pull模型
│   ├── 工作流程:定时HTTP GET → /metrics → 解析存储
│   ├── 优势:存活感知、配置集中、便于调试
│   └── Push场景:短生命周期任务 → Pushgateway
│
├── 核心组件
│   ├── Prometheus Server:拉取+存储+查询+告警
│   ├── Exporter:暴露指标(node/mysql/redis exporter)
│   ├── Pushgateway:接收短任务推送
│   ├── Alertmanager:告警处理与通知(见后续文章)
│   └── Grafana:可视化展示(见后续文章)
│
├── 数据模型
│   ├── 格式:metric_name{labels} value
│   ├── Counter:只增不减 → rate()/increase()
│   ├── Gauge:可增可减 → 直接读值
│   ├── Histogram:桶分布 → 服务端聚合
│   └── Summary:客户端分位数 → 无法跨实例聚合
│
├── node_exporter
│   ├── 安装:二进制 / Docker(挂载 /proc /sys /)
│   ├── 配置:prometheus.yml 添加 scrape_configs
│   └── 常用指标
│       ├── CPU:100 - idle% → rate()
│       ├── 内存:1 - avail/total
│       ├── 磁盘:1 - avail/size → 过滤tmpfs
│       └── 网络:rate(receive/transmit_bytes_total)
│
└── PromQL关键函数
    ├── rate():平滑增长率(告警推荐)
    ├── irate():瞬时增长率(面板推荐)
    ├── increase():时间段增量
    └── histogram_quantile():分位数

📝 写在最后

学习建议

  1. 理解 Pull 模型的设计哲学:为什么选 Pull 而不是 Push?这个设计决策背后的思考(服务发现、配置集中、存活感知)是面试常考的架构设计题。
  2. 熟悉四种指标类型:Counter/Gauge/Histogram/Summary 各自适用什么场景、怎么查询,这是基础知识中的基础。
  3. 动手写 PromQL:把上面的 CPU、内存、磁盘、网络 PromQL 在 Prometheus UI 里敲一遍,看看返回结果。纸上得来终觉浅。
  4. 搞清楚 rate() 和 irate() 的区别:这在面试和实际工作中都非常高频。

面试高频问题速答

Q:Prometheus 的 Pull 模型和 Push 模型有什么区别?

Pull 模型:Prometheus Server 定时主动拉取目标的 /metrics 端点数据。优势是天然感知目标存活(拉不到就是挂了)、配置集中、便于调试。Push 模型:目标主动推送数据到 Pushgateway,适用于短生命周期的批处理任务(如 CronJob),这类任务可能在 Pull 之前就执行完了。

Q:Counter 和 Gauge 有什么区别?

Counter 是只增不减的计数器(如请求总数),只能通过 rate() 或 increase() 计算变化率。Gauge 是可增可减的仪表盘(如 CPU 使用率),可以直接读取当前值。

Q:Histogram 和 Summary 有什么区别?

Histogram 在服务端维护预定义桶(bucket)的计数器,多个实例的数据可以在 Prometheus Server 端聚合,适合多副本场景。Summary 在客户端直接计算分位数(如 P99),精度更高但无法跨实例聚合。一般推荐用 Histogram。

相关推荐
晨陌y2 小时前
CentOS 7 部署 mysqld_exporter:MySQL 指标采集、Prometheus 告警与远程监控
mysql·centos·prometheus
倔强的小石头_1 天前
Ubuntu部署Prometheus与Alertmanager:systemd配置、告警对接及cpolar远程访问
数据库·ubuntu·prometheus
打工仔折腾 AI1 天前
Prometheus接入Pushgateway实战:二进制与Docker部署、指标推送与远程写入
后端·python·docker·容器·性能优化·prometheus·ai agent 实战
哈__1 天前
日志散在多台服务器怎么查?用 Promtail + Loki + Grafana 搭一套集中检索平台
运维·服务器·grafana
Elastic 中国社区官方博客2 天前
两个依赖和一个配置块:通过 Prometheus 远程写入将 Spring Boot 指标发送到 Elasticsearch
大数据·数据库·spring boot·elasticsearch·搜索引擎·全文检索·prometheus
User_芊芊君子3 天前
Prometheus接入Pushgateway实战:二进制与Docker部署、指标推送及远程上报
docker·容器·prometheus
lbb 小魔仙9 天前
OpenClaw + cpolar 实战:远程 NAS、分享小游戏、RDP,再配置公网 AI 入口
数据库·人工智能·redis·oracle·prometheus
zhoupenghui16810 天前
Golang pprof 工具详解:监控、压测与调优实战指南
prometheus·pprof
ggaofeng11 天前
prometheus时序数据库
prometheus