目录
前篇讲了prometheus配置方面,本篇将讲prom概念相关内容。
了解好概念才能用到prom
一、prometheus 相关概念
从prometheus官方文档知道 , prometheus相关概念主要是涉及三方面
即数据模型、metric(指标)类型、任务和实例
1.1 什么是TSDB时序数据库
Prometheus的存储层在历史上有着惊人的性能表现, -个单台服务器每秒可以摄取多达100万个采样,数百万个时间序列,同时仅占用令人惊叹的少量磁盘空间,这种强大的特效依赖于强大的时序数据库。
TSDB(Time Series Database时序列数据库,我们可以简单的理解为一个优化后用来处理时间序列数据的软件,并且数据中的数组是由时间进行索引的。
1.2 时序数据库的特点
- 大部分时间都是写入操作。
- 写入操作几乎是顺序添加,大多数时候数据到达后都以时间排序。
- 写操作很少写入很久之前的数据,也很少更新数据。大多数情况在数据被采集到数秒或者数分钟后就会被写入数据库。
- 删除操作-般为区块删除,选定开始的历史时间并指定后续的区块。很少单独删除某个时间或者分开的随机时间的数据。
- 基本数据大, -般超过内存大小。-般选取的只其-小部分且没有规律,缓存几乎不起任何作用。
- 读操作是十分典型的升序或者降序的顺序读。
- 高并发的读操作十分常见。
二、数据模型data model
直接看prome官网文档数据模型即可
Prometheus将所有数据存储为时间序列(time series)数据,每个时间序列数据都具有带时间戳的数据流,数据流都由其指标(metric)名称和一组键值对(也称为标签(label))唯一标识,即不同的标签代表不同的时间序列。我们可以基于这些标签很容易地对监控数据进行聚合、过滤和整理。除了存储的时间序列,Prometheus还可以作为查询结果,产生临时的派生时间序列。
Prometheus从根本上存储的所有数据都是时间序列具有时间戳的数据流只属于单个度量指标和该度量指标下的多个标签维度。
从前面我们添加的Node Exporter中我们访问web界面的target中可以访问到相关数据样本:我这里用http://192.168.3.21:9100/metrics为例子
#我在这里只截取了其中一部分
...
# HELP node_cpu_seconds_total Seconds the cpus spent in each mode.
# TYPE node_cpu_seconds_total counter
node_cpu_seconds_total{cpu="0",mode="idle"} 2360.89
node_cpu_seconds_total{cpu="0",mode="iowait"} 1.58
node_cpu_seconds_total{cpu="0",mode="irq"} 185.22
node_cpu_seconds_total{cpu="0",mode="nice"} 0.18
node_cpu_seconds_total{cpu="0",mode="softirq"} 69.25
node_cpu_seconds_total{cpu="0",mode="steal"} 0
node_cpu_seconds_total{cpu="0",mode="system"} 450.62
node_cpu_seconds_total{cpu="0",mode="user"} 68.63
node_cpu_seconds_total{cpu="1",mode="idle"} 2381.11
node_cpu_seconds_total{cpu="1",mode="iowait"} 1.11
node_cpu_seconds_total{cpu="1",mode="irq"} 151.87
node_cpu_seconds_total{cpu="1",mode="nice"} 0.77
node_cpu_seconds_total{cpu="1",mode="softirq"} 70.59
node_cpu_seconds_total{cpu="1",mode="steal"} 0
node_cpu_seconds_total{cpu="1",mode="system"} 445.02
node_cpu_seconds_total{cpu="1",mode="user"} 79.08
...
以非#号开头的数值就是我们采集到的一个数据样本, node_ cpu_ seconds_ _total 表明当前指标的名称(即统计当前cpu的状态)、{cpu="0" , "mode"="idel"}主要反映了样本里面不同的标签值, 我们可以根据标签进行不同的筛选和过滤,后面的浮点数表示采集到的数值。
2.1 Samples(样本)
prome官方文档也对Samples(样本)进行解释
sample即样本,按照某个时序以时间维度采集的数据,有序的样本形成了实际的时间序列数据列表,每个样本包括两方面内容:
·一个float64类型值(value)。
·毫秒级精度的时间戳(timestamp)。
对于没有按照顺序收集的样本,Prometheus会将其丢弃。
Prometheus会将所有采集到的样本数据以时间序列( time-series )的方式保存在内存数据库中,并且定时保存到硬盘上。time-series是按照时间戳和值的序列顺序存放的,我们称之为向量(vector).每条time- series通过指标名称(metrics name)和-组标签集(labelset)命名。如下所示,可以将time series理解为一个以时间为Y轴的数字矩阵:
^
│ . . . . . . . . . . . . . . . . . . . node_load1{instance="192.168.3.82:9100",job="centos8",note="测试"}
│ . . . . . . . . . . . . . . . . . . . node_load1{instance="192.168.3.21:9100",job="centos8",note="测试"}
│ . . . . . . . . . . . . . . . . . .
│ . . . . . . . . . . . . . . . . . .
v
<------------------ 时间 ---------------->
按照某个时序以时间维度采集的数据,称之为样本,一个样本包含有如下几个部分:
指标(metric) : metric name和描述当前样本特征的labelsets;
时间戳(timestamp) :一一个精确到毫秒的时间戳;
样本值(value) :一个float64的浮点型数据表示当前样本的值。
<--------------- metric ---------------------><-timestamp -><-value->
http_request_total{status="200", method="GET"}@1434417560938 => 94355
http_request_total{status="200", method="GET"}@1434417561287 => 94334
http_request_total{status="404", method="GET"}@1434417560938 => 38473
http_request_total{status="404", method="GET"}@1434417561287 => 38544
http_request_total{status="200", method="POST"}@1434417560938 => 4748
http_request_total{status="200", method="POST"}@1434417561287 => 4785
2.2 Metric(指标)和 labels(标签)
prome官方文档对 Metric和 labels 进行了解说。
metric即指标,指定监控目标系统测量特征,可以理解为定义了某个监控指标类型名称。
指标名称可以由ASCII字母、数字、下划线和冒号组成,但应该以字母开头,后面可以跟任意数量的字母、数字和下划线。而[a-zA-Z_:][azA-Z0-9_:]*是有效指标的正则表达式。
注意:冒号“:”是为用户定义的记录规则保留的。
label即标签,支持Prometheus的维度数据模型,是一个关键部分。相同监控指标名称的任何给定标签组合,都会标识该指标的特定维度实例化,基于这些维度,Prometheus可以使用查询语言对数据进行过滤和聚合。更改任何标签值,包括添加或删除标签,都将创建一个新的时间序列。
标签名称可以包含ASCII字母、数字和下划线,需要以字母a-z或A-Z开头,然后跟字母、数字和下划线。标签的有效匹配正则表达式为[a-zA-Z_][a-zA-Z0-9_]*。以__(双下划线)开头的标签名称,只能在系统内部使用。
标签值可以是任何UTF-8字符,也可以为空,但是在Prometheus服务器中,标签值为空可能令人困惑,
因为看起来就像没有这个标签一样
2.3 Notation(符号)
prome官方文档对 Notation 进行了解说。
notation即符号,Prometheus时序格式和OpenTSDB类似,是用符号表示时间序列的。在指定一个指标和一个或一组标签时,时间序列通常使用以下格式标识:
<metric name>{<label name>=<label value>, ...}
监控指标名称(metric name)用来说明被监控样本怎么称呼,标签反映的是当前样本的特征维度。例如,一个监控指标名称为api_http_requests_total,标签为method="POST"和handler="/messages"的时间序列可以这样写:
api_http_requests_total{method="POST", handler="/messages"}
三、metric types(指标类型)
在prom官方文档的 metric types 中知道有如下几种类型
3.1 Counter(计数器)
Counter是最常用的指标类型,是一个严格的另加指标,有如下特点:
- 其值从0开始只能增加,不会减少,可以理解为一个计数器,一种累加型的指标。
- 重启进程后,会被重置,例如在微服务架构中,服务实例是短暂的,在滚动更新、自动缩放等操作时,计数器就会被重置为0。
counter是表示单个单调递增计数器的累积度量,其值只能在重启时增加或重置为零。例如: CPU时间, API访问总次数,异常发生次数等等场景。这些指标的特点就是增加不减少。
不要使用计数器来暴露可能减少的值。例如,不要使用计数器来处理当前正在运行的进程数,而是使用gauge。看是好像没有多大的用处,其实我们可以根据这种数据类型来统计发生变化的增长率的变化,例如:
通过rate()函数获取HTTP请求量的增长率:
rate(http_ requests_ total[5m])
查询当前系统中,访问量前5的HTTP地址:
topk(10, http_ requests_ _total)
3.2 Gauge(仪表盘)
有些数据的值可能会随着时间的推移而上下浮动,这时可以使用Gauge类型的指标来跟踪此类数据,Gauge(仪表盘)类型的指标是一种常规指标,反映系统当前状态的快照,是对一个值的瞬时测量,有如下特点:
- 测量值是一个瞬时的数据,其值可以任意增加或减少。
- 重启进程后,会被重置。
gauge是一个度量指标,它表示一个既可以递增,又可以递减的值。
Gauge通常用于测量值,如温度或当前内存使用情况,但也可用于可以上下的"计数" ,例如并发请求的数量。用户的登录数据,内存的使用情况, cpu的负载情况等。大部分以前我们在zabbix里面定义的监控项,都可以用Gauge实现。
PS:一句话就是值是有变化的呗,就像名字那个仪表盘,不是有变化的吗
例如:
3.3 Histogram(直方图)
Histogram即直方图,形状与柱状图相似,用于表示在一段时间范围内对数据进行采样,对指定区间以及总数进行分组统计。典型的应用有请求持续时间、响应大小等等。在Prometheus系统中的查询语言中,它有三种作用:
- ·对每个采样点进行统计,对应到各个分类值中及bucket(可称为“桶”)。
- ·对每个采样点值累计和(sum)。
- ·对采样点的次数累计和(count)。
具有基本监控指标标准名称的直方图,在scrape期间暴露多个时间序列。实践中,直方图将会创建一个额外的带有_bucket后缀的指标,在Prometheus Server返回的自身样本数据中,可以找到该类型的Histogram的监控指标
# HELP prometheus_http_request_duration_seconds Histogram of latencies for HTTP requests.
# TYPE prometheus_http_request_duration_secondshistogram
prometheus_http_request_duration_seconds_bucket{handler="/",le="0.1"} 1
prometheus_http_request_duration_seconds_bucket{handler="/",le="0.2"} 1
prometheus_http_request_duration_seconds_bucket{handler="/",le="0.4"} 1
prometheus_http_request_duration_seconds_bucket{handler="/",le="1"} 1
prometheus_http_request_duration_seconds_bucket{handler="/",le="3"} 1
prometheus_http_request_duration_seconds_bucket{handler="/",le="8"} 1
prometheus_http_request_duration_seconds_bucket{handler="/",le="20"} 1
prometheus_http_request_duration_seconds_bucket{handler="/",le="60"} 1
prometheus_http_request_duration_seconds_bucket{handler="/",le="120"} 1
prometheus_http_request_duration_seconds_bucket{handler="/",le="+Inf"} 1
prometheus_http_request_duration_seconds_sum{handler="/"} 0.000126051
关于Histogram类型,使用的查询会对服务器的CPU有一定的消耗,最直观的反映就是查询结果的返回耗时情况。需要记住,每个独特的标签组合都被视为一个单独的时间序列,因此,通常的做法是尽量保持bucket的数量较小,以及直方图上的其他标签数量较少。
PS:Histogram :直方图类型,可以通过该类型获取分位数,计算分位点数据是在服务端完成的。
3.4 Summary(摘要)
Summary即摘要,类似于Histogram,常用于跟踪与时间相关的数据。典型的应用包括请求持续时间、响应大小等。Summary同样提供样本的count和sum功能;还提供quantiles功能,可以按百分比划分跟踪结果,例如,quantile取值0.95,表示取样本里面的95%数据。Histogram需要通过<basename>_bucket计算quantile,而Summary直接存储了quantile的值。
PS:Summary:摘要类型,类似于直方图,计算分位点数据是在客户端完成的。
使用ELK比较熟悉的同学对Historgram应该比较熟悉,主要是是用来进行分组的聚合运算,把相同节点数据放进分组里,然后进行分组统计。
histogram是柱状图, 在Prometheus系统中的查询语言中,有 三种作用:
- 对每个采样点进行统计(并不是一段时间的统计 ),打到各个桶(bucket)中
- 对每个采样点值累计和(sum)
- 对采样点的次数累计和(count)
四、jobs and instances(作业和实例)
在Prometheus中,任何被采集的目标,即每一个暴露监控样本数据的HTTP服务都称为一个实例(Instance),通常对应于单个进程。而具有相同采集目的的实例集合(比如为可伸缩性或可靠性而复制的流程)称为作业(Job)
例如,以下四个复制实例的API服务器作业:
job:
api-server
- instance 1:
1.2.3.4:5670
- instance 2:
1.2.3.4:5671
- instance 3:
5.6.7.8:5670
- instance 4:
5.6.7.8:5671
现在看一下在Prometheus中使用prometheus.yml配置文件添加的从Node exporter暴露的服务器中采集监控数据的内容:
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'centos8'
static_configs:
- targets: ['192.168.3.82:9100','192.168.3.21:9100']
在以上Job中,采用静态配置方式定义被监控目标,在当前主机上运行的Node exporter监控程序被称为一个实例(Instance),而具有相同目的这些实例,或者是同一个监控进程的多个副本进程则通过每一个作业(Job)进行管理。除了静态配置每个Job采集实例地址外,Prometheus还可以从自动发现的实例上采集监控数据。
Prometheus在采集目标数据的同时,会自动在时序的基础上附加如下标签,用于识别被采集的目标。
job:配置目标所属的job名称。
instance:被采样目标URL中的<host>:<port>部分。
如果这些标签中的任何一个已经存在于采集数据中,Prometheus会根据配置文件中的honor_labels来决定如何处理这些要被附加的标签。对于每个被采集的Instance,Prometheus都会在以下时间序列中存储一个样本(sample)。up{job="<job-name>",instance="<instance-id>"}:如果instance处于正常状态即可问,则为1,否则为0
scrape_duration_seconds{job="<job-name>",instance="<instance-id>"}:目标持续采集消耗时间。
scrape_samples_post_metric_relabeling{job="<job-name>",instance="<instance-id>"}:采集指标重新打标签后剩余的采样条数。
scrape_samples_scraped{job="<job-name>",instance="<instance-id>"}:从该目标数据源获取的样本。
其中,"UP"时间序列用于监控Instance可用性,即是否正常工作。可以通过使用"UP"表达式查询当前所有Instance的状态。