Prometheus 是一款开源的 监控和警报工具包,专为云原生和动态环境设计,由 SoundCloud 创建并于 2016 年加入 CNCF(云原生计算基金会)。其核心功能包括多维数据模型、灵活的查询语言(PromQL)、高效的时间序列数据库(TSDB)以及动态服务发现,适用于监控分布式系统和微服务架构。
一、核心组件
-
Prometheus Server
- 抓取(Scrape):定期从配置的目标(如应用、Exporters)拉取指标数据。
- 存储(Storage):将时间序列数据存储在本地或远程 TSDB 中。
- 查询(Query):通过 PromQL 提供实时数据分析能力。
-
Client Libraries
- 支持多种语言(Go、Java、Python等),用于在应用程序中嵌入监控代码,暴露自定义指标(如 HTTP 请求数、错误率)。
-
Exporters
- 将第三方系统(如 MySQL、Redis、Nginx)的监控数据转换为 Prometheus 可识别的格式。常用 Exporters 包括
node_exporter
(主机监控)、blackbox_exporter
(网络探测)等。
- 将第三方系统(如 MySQL、Redis、Nginx)的监控数据转换为 Prometheus 可识别的格式。常用 Exporters 包括
-
Push Gateway
- 用于接收短生命周期任务(如批处理作业)的指标数据,避免因任务终止导致数据丢失。
-
Alertmanager
- 处理来自 Prometheus 的警报,进行去重、分组、静默,并通过邮件、Slack、PagerDuty 等渠道发送通知。
-
Service Discovery
- 支持 Kubernetes、Consul、AWS EC2 等服务发现机制,自动识别动态环境中的监控目标。
二、数据模型
Prometheus 的指标由 名称(Metric Name) 和 标签(Labels) 唯一标识,采用键值对形式存储时间序列数据。
-
示例指标:
http_requests_total{method="POST", path="/api", status="200"} 1500
http_requests_total
是指标名称。method
、path
、status
是标签,用于多维过滤和聚合。1500
是当前时间点的值。
-
指标类型:
- Counter:累加值(如请求总数)。
- Gauge:瞬时值(如 CPU 使用率)。
- Histogram 和 Summary:用于统计分布(如请求延迟)。
三、数据如何传输到 Prometheus?
Prometheus 采用 Pull(拉取)模型 主动从监控目标获取数据,同时支持部分 Push(推送) 场景。具体数据传输方式如下:
1. 主动拉取(Pull)
-
核心机制:
Prometheus Server 定期通过 HTTP 协议从配置的目标(如应用程序、Exporters)拉取指标数据。 -
数据来源:
- Exporters:将第三方系统的监控数据转换为 Prometheus 兼容格式。
- 例如:
node_exporter
(主机监控)、mysql_exporter
(MySQL 监控)、blackbox_exporter
(HTTP/TCP 探测)。 - 暴露数据的默认路径:
http://<target>:<port>/metrics
。
- 例如:
- 应用程序内嵌 Client Libraries:
- 通过代码在应用中直接暴露指标(如 Go 的
prometheus/client_golang
库)。 - 示例:统计 HTTP 请求总数:
httpRequestsTotal = prometheus.NewCounter(prometheus.CounterOpts{ Name: "http_requests_total", Help: "Total HTTP requests", }) prometheus.MustRegister(httpRequestsTotal)
- 通过代码在应用中直接暴露指标(如 Go 的
- Exporters:将第三方系统的监控数据转换为 Prometheus 兼容格式。
-
配置方式:
在prometheus.yml
中定义抓取目标(scrape_configs
):scrape_configs: - job_name: 'node' static_configs: - targets: ['192.168.1.100:9100'] # node_exporter的地址 - job_name: 'web_app' metrics_path: '/metrics' static_configs: - targets: ['app-server:8080']
2. 被动接收(Push)
-
适用场景:
短生命周期任务(如批处理作业)无法等待 Prometheus 拉取,需主动推送数据。 -
Push Gateway 的作用:
- 临时存储推送的指标数据,供 Prometheus 后续拉取。
- 示例:通过
curl
推送数据到 Push Gateway:echo "batch_job_duration 300" | curl --data-binary @- http://push-gateway:9091/metrics/job/batch_job
四、数据如何存储?
Prometheus 将数据存储在本地时间序列数据库(TSDB)中,支持高效压缩和快速查询。
1. 存储结构
-
时间序列(Time Series):
每个指标由Metric Name
+Labels
唯一标识,数据按时间戳和值存储。
示例:http_requests_total{method="POST", path="/api"} @1625097600 → 1500 http_requests_total{method="GET", path="/home"} @1625097600 → 3000
-
数据分块(Blocks):
- 每个 Block 存储 2 小时的数据(可配置)。
- 旧数据通过压缩合并提升查询效率。
2. 存储目录
- 默认路径:
./data/
(可通过--storage.tsdb.path
配置)。 - 目录结构:
data/ ├── 01BKGTZQ1HHWHX8FJYQD6C6XTB # Block ID │ ├── chunks # 原始数据 │ ├── index # 索引文件 │ └── meta.json # 元数据 └── wal # 预写日志(用于崩溃恢复)
3. 长期存储
- 问题:本地 TSDB 默认保留 15 天,需扩展存储时长。
- 解决方案:
- Thanos:跨集群聚合数据,支持无限保留(依赖对象存储如 S3)。
- Cortex:多租户、水平扩展的长期存储方案。
五、完整流程示例
-
数据采集:
- 应用通过 Client Library 暴露指标
/metrics
。 node_exporter
采集主机指标(CPU、内存、磁盘)。
- 应用通过 Client Library 暴露指标
-
数据传输:
- Prometheus Server 每 15 秒拉取一次
/metrics
端点。
- Prometheus Server 每 15 秒拉取一次
-
数据存储:
- 指标按时间序列写入本地 TSDB。
-
查询与报警:
- 用户通过 PromQL 查询
rate(http_errors_total[5m]) > 0.1
。 - 触发报警后,Alertmanager 发送通知到 Slack。
- 用户通过 PromQL 查询
-
可视化:
- Grafana 仪表盘展示实时请求速率和资源利用率。