Prometheus
是一个开源的监控系统
和时序(time series)数据库
,2016年加入 CNCF,云原生监控平台。Prometheus
使用Go语言开发,是Google BorgMon
监控系统的开源实现。
介绍
Prometheus 基于 Go 语言开发,是一套开源的系统监控报警框架,能轻松支持上万台规模的集群。特点如下:
- 内置
时序数据库(TSDB, Time Series Database)
,支持双精度浮点类型数据存储(不支持文本,如日志需要使用loki)
- 支持多维数据模型,由
度量名
和 键值对
组成的时间序列
- 支持
PromQL(Prometheus Queue language)
查询语言,结合数据标签实现数据的聚合、切割、切片等功能
- 支持 HTTP pull 方式和 PushGateway 方式采集数据
- pull 优势:采集目标、指标和频率均在 Server 端配置;且数据是在采集端预先聚合
- 支持服务发现和静态配置两种发现方式
- 支持第三方仪表盘,如 grafana
- 原生支持 Kubernetes
Prometheus 的局限性:
- 不适合存储事件和日志
- 不支持100%准确数据
- 不支持大量历史数据的存储,长期存储数据建议采用 Influxdb、OpenTSDB 等
- 集群不太成熟
源码
Prometheus 架构
组件说明:
Prometheus Server
:负责数据的采集和存储
Retrieval
:数据采集器定义了 Prometheus Server 从哪些地方拉取数据
TSDB
:时序数据存储,默认保留60天数据
Http server
:通过 PromQL 查询数据
- 数据采集:
Prometheus
使用的是 Pull
模型,Prometheus Server
通过 HTTP 的 pull 方式到各个目标 抓取(scrape)
监控数据,支持 4 中方式:
Exporters
:用于未内建 Instrumentation
,一个单独的 Exporter 程序,从应用程序中 拉取
监控数据和聚合原生数据,并转换为符合 Prometheus 格式的数据暴露出来
- Exporter 以 Web API 的形式对外暴露数据采集接口
Instrumentation
:附加到应用程序中,用于暴露该程序指标数据的客户端库。一般通过 HTTP 协议从应用获取符合 Prometheus 格式的数据
Pushgateway
:从 Pushgateway
中拉取
监控数据,使用如下场景:
- 瞬时数据:对于一些以临时性Job运行的组件,Prometheus 可能还没有来得及从中 pull 监控数据的情况下,这些 Job 已经结束了,Job 运行时可以在运行时将监控数据
推送
到 Pushgateway 中,Prometheus 从 Pushgateway 中拉取数据,防止监控数据丢失
- 网络隔离问题
Prometheus
从其他的 Prometheus Server
中拉取数据
- 数据展示
- Prometheus web UI
- Grafana
- PromQL:是Prometheus的查询语句,利用PromQL可以和一些WEBUI(如Grafana)集成
- Alertmanager:是一个独立于 Prometheus 的外部组件,用于监控系统的告警,通过配置文件可以配置一些
告警规则
,Prometheus 会把告警推送到 AlertManager,AlertManager 接受到告警指标后,基于 告警路由(alerm route)
向接收人 receivers
发送告警信息
Service discovery
:服务自动发现,Prometheus可以动态的发现一些服务,拉取数据进行监控,如从 DNS、Kubernetes、Consul 中发现
- 支持的后端存储
- 支持联邦集群
认证:
监控数据模型
Prometheus 的数据模型支持多维自定义,这个模型下的 时序数据
由 指标名称
和一组 key/value标签
组成。
Key 格式如下:
<metric name>{<label name>=<label value>, ...}
例如:
api_http_requests_total{method="POST", handler="/messages"} 1000
|---metric name/key---|---------------Labels--------------|-value-|
说明:
metric name(指标名称)
。给监测对象的指标取的一个名字,例如 api_http_requests_total
- 指标名称须遵守命名规范:ascii 字符,数字,下划线以及冒号组成,满足正则表达式:
[a-zA-Z_:][a-zA-Z0-9_:]*
的查询需求
label(标签)
表示对一条时间序列不同维度的识别,例如对于 api_http_requests_total{method="POST", url="/messages"}
中有 method 表示请求用的是 GET 还是 POST
- 标签名称须遵守命名规范:ascii 字符,数字,下划线以及冒号组成,满足正则表达式:
[a-zA-Z_][a-zA-Z0-9_]*
的查询需求
- 标签值:任意 Unicode 值
- 以
__
开头的为 Prometheus 系统预留的
- 相同指标名称的数据模型无论增加或减少标签都会形成一条新的时间序列
- 时序数据 vs 关系型数据库:
指标名称
对应 表名
标签
对应 表的字段
,另外指标也是一个字段
timestamp
是表数据的主键
- 指标的值就是指标字段数据的值
时序样本(Samples)
是按照某个时序以时间维度采集的数据,每个时序样本的组成如下:
- 一个 float64 的值
- 一个毫秒精度的 unix 时间戳
Metric Type
Prometheus的时序数据包含以下四种指标类型:
Counter
: 累计计数,Counter的特点是一直增加不会减少,可以重置为 0
Gauge
:记录起伏特征的指标数值,可以增加或减少
- Histogram:直方图,在一段时间内对数据进行采用,并计入预先配置的bucket中,并可对记录的内容分组和聚合(count、sum等)
- Prometheus 取值间隔的划分采用累计(Cumulative)区间间隔机制,即每个 bucket 中的样本均包含前面所有的样本
- 常用于跟踪事件发生的规模,如请求耗时、响应大小
- 命名
<basename>_bucket{le=""}
<basename>_sum
<basename>_count
- 例如响应时间小于500毫秒的多少次、500毫秒~1000毫秒之间多少次、1000毫秒以上的多少次
Summary
:摘要,与 Histogram 类似,按百分比记录结果,对于每个采样点进行统计,并形成分位图
- 命名
<basename>{quantile="x"}
,其中 0<=x<=1
<basename>_sum
<basename>_count
- summary 是采样点分位图统计,使用场景:请求持续时间和响应大小
- 如:统计低于60分不及格的同学比例,统计低于80分的同学比例,统计低于95分的同学比例
Job 和 Instance
例如:
- job_name: api-server
static_configs:
- targets:
- instance1:port
- instance2:port
- instance3:port
- instance4:port
Prometheus 在从目标采集数据时会自动附加一些标签,用于识别被采集的目标:
- job:
配置的job名称
- instance:
<host>:<port>