Prometheus入门教程
Prometheus是一个基于时间序列存储的开源监控&报警系统,提供原生Web页面,支持数据的查询/聚合/曲线生成,metrics数据呈现一般接入Grafana。
特点
- 多维数据模型,时间序列由metric名字和K/V标签标识
- 灵活的查询语言(PromQL)
- 单机模式,不依赖分布式存储
- 基于HTTP采用pull方式收集数据
- 支持push数据到中间件(pushgateway)
- 通过服务发现或静态配置发现目标
- 多种图表和仪表盘
组件
Prometheus生态系统由多个组件构成,其中多是可选的,根据具体情况选择
- Prometheus server - 收集和存储时间序列数据
- client library - 用于client访问server/pushgateway
- pushgateway - 对于短暂运行的任务,负责接收和缓存时间序列数据,同时也是一个数据源
- exporter - 各种专用exporter,面向硬件、存储、数据库、HTTP服务等
- alertmanager - 处理报警
- 其他各种支持的工具
基本概念
数据模型
metric名字和标签集合确定一个唯一的时间序列;时间序列数据样本由一个毫秒精度的时间戳和一个float64类型的值组成。
例如,一个名为http_request的metric,标签有method/host/uri等,表现此metric的多个维度,可表示为http_request{method: “”, host: “”, uri: “”, …},那么不同的标签组合将确定不同的时间序列。
http_request{method: "POST"}
请求类型为POST的时间序列http_request{host: "host-1"}
目标主机为host-1的时间序列http_request{host: "host-2", uri: "/index.htm"}
目标主机为host-2同时uri为index.htm的时间序列http_request{method: "GET", host: "host-3"}
请求类型是GET同时目标主机为host-3的时间序列
metric类型
client libraries提供了四种metric类型,包括Counter、Gauge、Histogram、Summary。
Counter
计数器,只允许增加或重置为0,不允许减少,比如服务的请求数。Counter支持用rate()函数计算平均值,比如QPS。建议使用 _total 作为后缀命名。
Gauge
非固定的值,比如CPU负载 、内存使用量。
作者起初没有充分理解时间序列的概念,试图使用Gauge记录请求的响应时间,后来发现这是个错误。
Gauge实际是一个值,其变化取决于server是否采集了数据,衡量的是一个事物的状态变化,比如内存使用量,内存始终是那个内存,只是其使用量会发生变化。
回到请求响应时间的场景,因为请求不是固定的,一秒内可能处理几千个请求,即使每个请求的响应时间都记录到Gauge,server采集到的也只是采集时刻前最后一个请求的响应时间,而这个值无法代表采集间隔期间其他请求的响应时间,没有任何说服力。
Histogram
采样观测值,可进行分位计算和数据聚合,计算在server端完成。
一个名为<basename>的metric,其histogram有3个固定的时间序列
<basename>_bucket
不同bucket下的观测值的累加数量<basename>_sum
观测值的总和<basename>_count
观测值的数量
Summary
采样观测值,与histogram不同的是,数量/总和/分位的计算在client端完成,计算结果存在server。因为没有最初的metric数据,所以summary不支持数据聚合。
一个名为<basename>的metric,其summary有3个固定的时间序列
<basename>{quantile="<φ>"}
<basename>_sum
观测值的总和<basename>_count
观测值的数量
关于job和instance标签
instance是指收集数据的目标端点,一般对应于一个进程;而job表示实现同一功能或目标的一组instance。
Prometheus采集到数据后自动为其附加job和instance标签,其中job由Prometheus配置文件定义,instance是目标数据源的地址<host>:<port>
。
查询
Prometheust提供函数表达式语言,用户可以实时地查询和聚合时间序列数据,表达式计算结果可以曲线图(Prometheus web graph)和表格(Prometheus web console)的形式呈现,也通过HTTP API由外部系统消费。
表达式语言数据类型
Prometheus表达式语言中,一个表达式或子表达式的计算结果是下列四个类型之一:
- instant vector 即时向量,位于同一时间点的一组时间序列,每个时间序列具有一个采样
- range vector 范围向量,位于同一时间段的一组时间序列,每个时间序列具有一系列采样
- scalar 标量,一个浮点数值
- string 字符串,一个字符串值
不同的使用场景,需要特定类型的表达式,例如,只有返回instant vector的表达式可以直接用于绘图。
时间序列选择器
instant vector selectors
即时向量选择器允许选择一组时间序列,每个时间序列在目标时间点都有一个采样,最简单的形式是指定一个metric名字。
例如,返回metric名为http_requests_total的全部时间序列:
http_requests_total
可以用{}
附加标签对时间序列进行过滤。
例如,返回metric名为http_requests_total、job
是prometheus、group
是canary的全部时间序列:
http_requests_total{job="prometheus",group="canary"}
也支持正则表达式:
=
等于!=
不等于=~
满足正则匹配!~
不满足正则匹配
例如,返回metric名为http_requests_total、environment
为staging/testing/development其中之一、method
不是GET的全部时间序列。
http_requests_total{environment=~"staging|testing|development",method!="GET"}
标签匹配可以不给定metric名字,返回的是具有此标签值的全部时间序列;如果标签匹配目标是一个空值(空字符串),返回不包含此标签的全部时间序列。
向量选择器规定至少要有一个标签的匹配目标不是空值。
{job=~".*"} # 错误,可能是空值
{job=~".+"} # 正确,非空值
{job=~".*",method="get"} # 正确,job可能是空值,method是非空值
标签匹配器可使用内部标签__name__
实现metric名字匹配。表达式http_requests_total
等同于{__name__="http_requests_total"}
。
其他匹配符也可使用,例如,下面表达式返回所有名字以http_
开头的metrics。
{__name__=~"^http_.*"}
range vector selectors
范围向量选择器与即时向量选择器工作原理相同,只不过返回当前时间以前的一系列采样。
时间范围由附加在向量选择器尾部的[]
指定,具体的值由数字和单位组成,时间单位包括:
s
- 秒m
- 分钟h
- 小时d
- 天w
- 星期y
- 年
例如,返回5分钟内metric名为http_requests_total、job
是prometheus的全部时间序列。
http_requests_total{job="prometheus"}[5m]
offset modifier
offset
修饰符允许在单个即时向量或范围向量查询中设置相对于当前时间的时间偏移。
下面的表达式返回http_requests_total
5分钟前的值:
http_requests_total offset 5m
语法上offset
修饰符应紧跟在selector后面,例如:
sum(http_requests_total{method="GET"} offset 5m) //正确
sum(http_requests_total{method="GET"}) offset 5m //错误
同样适用于范围向量查询,下面表达式返回http_requests_total
一周前的5分钟的QPS:
rate(http_requests_total[5m] offset 1w)
函数
内置函数很多,说几个使用过的,其他函数可参考https://prometheus.io/docs/prometheus/latest/querying/functions/
函数 | 功能 |
---|---|
rate | 计算每秒平均值,仅适用于Counter,例如统计QPS |
sum | 计算求和 |
histogram_quantile | 计算分位值 |
注意事项
-
时间对齐
TODO
-
数据过期
如果一个时间序列超过5分钟没有采集到数据,即为过期,具体表现为该时间序列从图中消失。
-
避免慢查询和过载
如果数据量很大,可能导致绘图超时和server/browser过载。在未知数据上构建查询,建议先在Web Console下调试,确保结果合理(最多有几百个时间序列)。数据经过充分地过滤或聚合后,再切换到Web Graph。如果还是超时,可使用recoding rule预先生成数据。