1、prometheus简介
Prometheus是一个开源的系统监控和报警系统,现在已经加入到CNCF基金会,成为继k8s之后第二个在CNCF托管的项目,在k8s容器管理系统中,通常会搭配Prometheus进行监控,同时也支持多种exporter采集数据,还支持pushgateway进行数据上报,Prometheus性能足够支撑上万台规模的集群

2、prometheus特点
1)多维度数据模型
2)每一个时间序列数据都是由metric度量指标名称和它的标签labels键值对集合唯一确定:
这个metris度量指标名称指监控目标系统的测量特征(如:http_requests_total - 接收http请求总计数)。labels开启了Prometheus的多维数据模型,对于相同的度量名称,通过不同标签列表的结合,会形成特定的度量维度实例,(例如:所有包含度量名称为/api/tracks的http请求,打上method=POST的标签,则形成了具体的http请求)。这个查询语言在这些度量和标签列表的基础上进行过滤和聚合。改变任何度量上的任何标签值,则会形成新的时间序列图;
3)灵活的查询语言(PromQL)
4)可以对采集的metrics指标进行加法,乘法,连接等操作;
5)可以直接在本地部署,不依赖其他分布式存储;
6)通过基于HTTP的pull方式采集时序数据;
7)可以通过中间网关pushgateway的方式把时间序列数据推送到Prometheus server端;
8)可以通过服务发现或者静态配置来发现目标服务对象(targets);
9)有多种可视化图形界面,如grafana等;
10)高效的存储,每个采集数据占3.5 bytes左右,300万的时间序列,30s间隔,保留60天,消耗磁盘大概200G;
11)做高可用,可以对数据做异地备份,联邦集群,部署多套Prometheus,gushgateway上报数据

3、样本
在时间序列中的每一个点称为一个样本(sample),样本由以下三部分组成:
指标(metric):指标名称和描述当前样本特征的labelsets;
时间戳(timestamp):一个精确到毫秒的时间戳;
样本值(value):一个folat64的浮点型数据表示当前样本的值
表示方式:
通过如下表达方式表示指定指标名称和指定标签集合的时间序列:
{=, ...}
例如,指标名称为 api_http_requests_total,标签为 method="POST" 和 handler="/messages" 的时间序列可以表示为:
api_http_requests_total{method="POST", handler="/messages"}

4、Prometheus组件介绍

Prometheus server:用于收集和存储时间序列数据

client library:客户端库,检测应用程序代码,当Prometheus抓取实例的HTTP端点时,客户端库会将所有跟踪的metres指标的当前状态发送到Prometheus server端

exporters:Prometheus支持多种exporter,通过exporter可以采集metres数据,然后发送到Prometheus server端,所有向Prometheus server提供监控数据的程序都可以被称为 exporter

alertmanager:从Prometheus server端接收到alerts后,会进行去重,分组,并路由到相应的接收方,发出报警,常见的接收方式有:电子邮件,微信,钉钉,slack等

grafana:监控仪表盘,可视化监控数据

pushgateway:各个目标主机可上报数据到pushgateway。然后Prometheus server统一从pushgateway拉取数据

prometheus 多个mysql prometheus 多个指标path_时间序列


从上图可发现,Prometheus整个生态圈组成主要包括Prometheus server,exporter,pushgateway,alertmanager,grafana,web ui界面,Prometheus server由三个部分组成,Retrieval,Storage,PromQL

1)Retrieval负责在活跃的target主机上抓取监控指标数据

2)Storage存储主要是把采集到的数据存储到磁盘中

3)Grafana可接入prometheus数据源,把监控数据以图形化形式展示出

5、Prometheus工作流程
1)Prometheus server可定期从活跃的(up)目标主机上(target)拉取监控指标数据,目标主机的监控数据可通过配置静态job或者服务发现的方式被Prometheus server采集到,这种方式默认的pull方式拉取指标;也可通过pushgateway把采集的数据上报到Prometheus server;还可通过一些组件自带的exporter采集相应组件的数据;
2)Prometheus server把采集到的监控指标数据保存到本地磁盘或者数据库;
3)Prometheus采集的监控指标数据按时间序列存储,通过配置报警规则,把触发的报警发送到alertmanger;
4)alertmanger通过配置报警接收方,发送报警到邮件,微信或者钉钉等;
5)Prometheus自带的web ui界面提供PromQL查询语言,可查询监控数据;
6)Grafana可接入Prometheus数据源,把监控数据以图形化形式展示出来

6、Prometheus和zabbix对比分析

prometheus 多个mysql prometheus 多个指标path_prometheus 多个mysql_02

7、Prometheus的四种数据类型
counter:counter是计数器类型,用于累计值,例如记录请求次数、任务完成数、错误发生次数,一直增加,不会减少,重启进程后,会被重置
例如:
http_response_total{method="GET",endpoint="/api/tracks"} 100
http_response_total{method="GET",endpoint="/api/tracks"} 160
counter类型数据可以让用户方便的了解事件产生的速率变化,在PromQL内置的相关操作函数可以提供相应的分析,比如HTTP应用请求量来进行说明:
通过rate()函数获取HTTP请求量的增长率
rate(http_requests_total[5m])
查询当前系统中,访问量前10的HTTP地址
topk(10, http_requests_total)

gauge:gauge是测量器类型,常规数值,例如温度变化、内存使用变化,可变大,可变小,重启进程后,会被重置
memory_usage_bytes{host="master-01"} 100
memory_usage_bytes{host="master-01"} 30
memory_usage_bytes{host="master-01"} 50
memory_usage_bytes{host="master-01"} 80
对于 Gauge 类型的监控指标,通过 PromQL 内置函数 delta() 可以获取样本在一段时间内的变化情况,例如,计算 CPU 温度在两小时内的差异:
dalta(cpu_temp_celsius{host="zeus"}[2h])
你还可以通过PromQL 内置函数 predict_linear() 基于简单线性回归的方式,对样本数据的变化趋势做出预测。例如,基于 2 小时的样本数据,来预测主机可用磁盘空间在 4 个小时之后的剩余情况:
predict_linear(node_filesystem_free{job="node"}[2h], 4 * 3600) < 0

histogram:histogram是柱状图,在Prometheus系统的查询语言中,有三种作用
1)在一段时间范围内对数据进行采样(通常是请求持续时间或响应大小等),并将其计入可配置的存储桶(bucket)中,后续可通过指定区间筛选样本,也可以统计样本总数,最后一般将数据展示为直方图
2)对每个采样点值累计和(sum)
3)对采样点的次数累计和(count)
度量指标名称:[basename]_上面三类的作用度量指标名称
1)[basename]_bucket{le="上边界"}, 这个值为小于等于上边界的所有采样点数量
2)[basename]_sum
3)[basename]_count
小结:如果定义一个度量类型为hostogram,则Prometheus会自动生成三个对应的指标
在大多数情况下人们都倾向于使用某些量化指标的平均值,例如CPU的平均使用率、页面的平均响应时间。这种方式的问题很明显,以系统API调用的平均响应时间为例:如果大多数API请求都维持在100ms的响应时间范围内,而个别请求的响应时间需要5s,那么就会导致某些WEB页面的响应时间落到中位数的情况,而这种现象被称为长尾问题.
为了区分是平均的慢还是长尾的慢,最简单的方式就是按照请求延迟的范围进行分组。例如,统计延迟在010ms之间的请求数有多少,而1020ms之间的请求数又有多少。通过这种方式可以快速分析系统慢的原因。Histogram 和 Summary 都是为了能够解决这样问题的存在,通过 Histogram 和 Summary 类型的监控指标,我们可以快速了解监控样本的分布情况.
Histogram类型的样本会提供三种指标(假设指标名称为):
样本的值分布在 bucket 中的数量,命名为 _bucket{le="<上边界>"}。解释的更通俗易懂一点,这个值表示指标值小于等于上边界的所有样本数量.
1)在总共2次请求当中。http 请求响应时间 <=0.005 秒 的请求次数为0
io_namespace_http_requests_latency_seconds_histogram_bucket{path="/",method="GET",code="200",le="0.005",} 0.0
2)在总共2次请求当中。http 请求响应时间 <=0.01 秒 的请求次数为0
io_namespace_http_requests_latency_seconds_histogram_bucket{path="/",method="GET",code="200",le="0.01",} 0.0
3)在总共2次请求当中。http 请求响应时间 <=0.025 秒 的请求次数为0
io_namespace_http_requests_latency_seconds_histogram_bucket{path="/",method="GET",code="200",le="0.025",} 0.0
io_namespace_http_requests_latency_seconds_histogram_bucket{path="/",method="GET",code="200",le="0.05",} 0.0
io_namespace_http_requests_latency_seconds_histogram_bucket{path="/",method="GET",code="200",le="0.075",} 0.0
io_namespace_http_requests_latency_seconds_histogram_bucket{path="/",method="GET",code="200",le="0.1",} 0.0
io_namespace_http_requests_latency_seconds_histogram_bucket{path="/",method="GET",code="200",le="0.25",} 0.0
io_namespace_http_requests_latency_seconds_histogram_bucket{path="/",method="GET",code="200",le="0.5",} 0.0
io_namespace_http_requests_latency_seconds_histogram_bucket{path="/",method="GET",code="200",le="0.75",} 0.0
io_namespace_http_requests_latency_seconds_histogram_bucket{path="/",method="GET",code="200",le="1.0",} 0.0
io_namespace_http_requests_latency_seconds_histogram_bucket{path="/",method="GET",code="200",le="2.5",} 0.0
io_namespace_http_requests_latency_seconds_histogram_bucket{path="/",method="GET",code="200",le="5.0",} 0.0
io_namespace_http_requests_latency_seconds_histogram_bucket{path="/",method="GET",code="200",le="7.5",} 2.0
4)在总共2次请求当中。http 请求响应时间 <=10 秒 的请求次数为 2
io_namespace_http_requests_latency_seconds_histogram_bucket{path="/",method="GET",code="200",le="10.0",} 2.0
io_namespace_http_requests_latency_seconds_histogram_bucket{path="/",method="GET",code="200",le="+Inf",} 2.0
所有样本值的大小总和,命名为 _sum。
5)实际含义: 发生的2次 http 请求总的响应时间为 13.107670803000001 秒
io_namespace_http_requests_latency_seconds_histogram_sum{path="/",method="GET",code="200",} 13.107670803000001
样本总数,命名为 _count。值和 _bucket{le="+Inf"} 相同。
6)实际含义: 当前一共发生了 2 次 http 请求
io_namespace_http_requests_latency_seconds_histogram_count{path="/",method="GET",code="200",} 2.0
注意:
bucket 可以理解为是对数据指标值域的一个划分,划分的依据应该基于数据值的分布。注意后面的采样点是包含前面的采样点的,假设 xxx_bucket{...,le="0.01"} 的值为 10,而 xxx_bucket{...,le="0.05"} 的值为 30,那么意味着这 30 个采样点中,有 10 个是小于 0.01s的,其余 20 个采样点的响应时间是介于0.01s 和 0.05s之间的.
可以通过 histogram_quantile() 函数来计算 Histogram 类型样本的分位数。分位数可能不太好理解,你可以理解为分割数据的点。我举个例子,假设样本的 9 分位数(quantile=0.9)的值为 x,即表示小于 x 的采样值的数量占总体采样值的 90%。Histogram 还可以用来计算应用性能指标值(Apdex score).

summary:与 Histogram 类型类似,用于表示一段时间内的数据采样结果(通常是请求持续时间或响应大小等),但它直接存储了分位数(通过客户端计算,然后展示出来),而不是通过区间来计算。它也有三种作用:
1)对于每个采样点进行统计,并形成分位图。(如:正态分布一样,统计低于60分不及格的同学比例,统计低于80分的同学比例,统计低于95分的同学比例)
2)统计班上所有同学的总成绩(sum)
3)统计班上同学的考试总人数(count)
带有度量指标的[basename]的summary 在抓取时间序列数据有如命名。
1)观察时间的φ-quantiles (0 ≤ φ ≤ 1), 显示为[basename]{分位数="[φ]"}
2)[basename]_sum, 是指所有观察值的总和
3)[basename]_count, 是指已观察到的事件计数值
样本值的分位数分布情况,命名为 {quantile="<φ>"}。
1)含义:这 12 次 http 请求中有 50% 的请求响应时间是 3.052404983s
io_namespace_http_requests_latency_seconds_summary{path="/",method="GET",code="200",quantile="0.5",} 3.052404983
2)含义:这 12 次 http 请求中有 90% 的请求响应时间是 8.003261666s
io_namespace_http_requests_latency_seconds_summary{path="/",method="GET",code="200",quantile="0.9",} 8.003261666
所有样本值的大小总和,命名为 _sum。
1含义:这12次 http 请求的总响应时间为 51.029495508s
io_namespace_http_requests_latency_seconds_summary_sum{path="/",method="GET",code="200",} 51.029495508
样本总数,命名为 _count。
1)含义:当前一共发生了 12 次 http 请求
io_namespace_http_requests_latency_seconds_summary_count{path="/",method="GET",code="200",} 12.0
现在可以总结一下 Histogram 与 Summary 的异同:
它们都包含了 _sum 和 _count 指标
Histogram 需要通过 _bucket 来计算分位数,而 Summary 则直接存储了分位数的值。
prometheus_tsdb_wal_fsync_duration_seconds{quantile="0.5"} 0.012352463
prometheus_tsdb_wal_fsync_duration_seconds{quantile="0.9"} 0.014458005
prometheus_tsdb_wal_fsync_duration_seconds{quantile="0.99"} 0.017316173
prometheus_tsdb_wal_fsync_duration_seconds_sum 2.888716127000002
prometheus_tsdb_wal_fsync_duration_seconds_count 216
从上面的样本中可以得知当前Promtheus Server进行wal_fsync操作的总次数为216次,耗时2.888716127000002s。其中中位数(quantile=0.5)的耗时为0.012352463,9分位数(quantile=0.9)的耗时为0.014458005s.