天天看点

深入Prometheus设计一 指标含义二 指标分类三 数据采集四 服务发现五 数据处理

本次读后感来自于《深入浅出Prometheus:原理、应用、源码与拓展详解》

书籍链接https://item.jd.com/12573580.html

一 指标含义

Prometheus的所有监控指标(Metric)被统一定义为

深入Prometheus设计一 指标含义二 指标分类三 数据采集四 服务发现五 数据处理

指标定义涉及指标名称和标签这两部分

1.指标名称(metric name)

指标名称用于说明指标的含义,例如http_request_total代表HTTP的请求总数。指标名称必须由字面、数值下画线或者冒号组成,符合正则表达式[a-zA-Z_:][a-zA-Z0-9_:]*,其中的冒号指标不能用于exporter。

2.标签(label)

标签可体现指标的维度特征,用于过滤和聚合。它通过标签名(label name)和标签值(label value)这种键值对的形式,形成多种维度。例如,对于指标 http_request_total,可以有{status=“200”,method=“POST”}和{status=“200”,method=“GET”}这两个标签。在需要分别获取GET和POST返回200的请求时,可分别使用上述两种指标;在需要获取所有返回200的请求时,可以通过http_request_total{status=“200”}完成数据的聚合,非常便捷和通用。指标的某些标签是以“__”开头的,这些标签是在Prometheus系统内部使用的。在形式上,http_request_total{status=“200”} 和{name=“http_request_total”,status=“200”}代表相同的指标。Prometheus指标采用标签的方式能够很好地与容器结合,无论是原生Docker还是Kubernetes,都通过标签关联资源。

二 指标分类

Prometheus指标分为Counter(计数器)、Gauge(仪表盘)、Histogram(直方图)和Summary(摘要)这4类

1.Counter

Counter是计数器类型,它的特点是只增不减,例如机器启动时间、HTTP访问量等。

Counter 具有很好的不相关性,不会因为机器重启而置0。我们在使用 Counter指标时,通常会结合 rate()方法获取该指标在某个时间段的变化率,例如,“HTTP请求总量”指标就属于典型的Counter指标,通过对它进行rate()操作,可以得出请求的变化率

2.Gauge

Gauge是仪表盘,表征指标的实时变化情况,可增可减,例如CPU和内存的使用量、网络 I/O 大小等,大部分监控数据都是 Gauge 类型的。如图2-3所示是内存使用量监控图,内存使用量随着时间的推移不断变化

3.Summary

Summary 同 Histogram 一样,都属于高级指标,用于凸显数据的分布状况。如果需要了解某个时间段内请求的响应时间,则通常使用平均响应时间,但这样做无法体现数据的长尾效应。例如,一个HTTP服务器的正常响应时间是30ms,但有很少几次请求耗时3s,通过平均响应时间很难甄别长尾效应,这时可以通过Histogram或者Summary展现。

Histogram和Summary这两种指标类型在本质上是可以相互转化的。这里先了解一下数据分位:φ代表分位数,0≤φ≤1,分位数是在N个观测值中按数量φ·N排序的观测值。

例如,0.9分位数代表第90%位置上的数,如果总数是100个,那么将是第90个数。Summary是采样点分位图统计,用于得到数据的分布情况。

例如,如果在要统计的班级中,有90%学生的成绩低于93分,有95%学生的成绩低于96分,则采用Summary能够更好地展示数据的分布情况。

我们可以将Summary看作客户端分位,它的优势是无须消耗服务端资源,但缺点也很明显:首先,与 Histogram 采用 Counter 计数器统计的方式相比,Summary会消耗更多的资源;其次,通过Summary计算的指标不能再获取平均数或者关联其他指标等,所以Summary指标一般只适用于独立的监控指标,例如垃圾回收时间等。

4.Histogram

Histogram反映了某个区间内的样本个数,通过{le=“上边界”}指定这个范围内的样本数。Prometheus中表示每个本地存储序列保存的chunk数量的指标prometheus_local_storage_series_chunks_persisted就属于Histogram指标类型

三 数据采集

和采用Push方式采集监控数据不同,Prometheus采用 Pull方式采集监控数据。这两种监控数据采集方式各有优缺点:采用Push方式时,Agent主动上报数据,采用Pull方式时,监控中心(Master)拉取 Agent的数据。其主要区别在于 Agent和Master的主动、被动关系

深入Prometheus设计一 指标含义二 指标分类三 数据采集四 服务发现五 数据处理

为了兼容 Push方式,Prometheus 提供了 Pushgateway组件。Pushgateway组件接收客户端发送过来的数据,按照 Job 和 Instance 两个层级进行组织,支持数据的追加和删除,并且为防止数据丢失,还支持本地存储。

1.实时性

Push方式的实时性相对较好,可以将采集数据立即上报到监控中心。Pull 方式通常进行周期性采集,采集时间为30s 或者更长时间。所以,如果对监控系统的实时性要求非常高,则建议采用Push方式。

2.状态保存

Push 方式通常在采集完成后立即上报,本地不会保存采集数据,Agent 本身是没有状态的,而Master需要维护各种Agent状态。Pull 方式正好相反,Agent 本身需要有一定的数据存储能力,Master 只负责简单的数据拉取,而且Master本身可以做到无状态。

3.控制能力

采用Push方式时,控制方为Agent,Agent上报的数据决定了上报的周期和内容。采用Pull方式时,Master更加主动,控制采集的内容和频率。

4.配置的复杂性

采用Push方式时,通常每个 Agent都需要配置Master的地址。采用Pull方式时,通常通过批量配置或者自动发现来获取所有采集点,相对简单,并且可以做到和 Agent充分解耦,Agent可以不用感知Master的存在

四 服务发现

静态文件配置和动态发现

1.静态文件配置

静态文件配置是一种传统的服务发现方式,一般适用于有固定的监控环境、IP地址和统一的服务接口的场景,需要在配置中指定采集的目标。

例如,指定采集本地8080端口的Agent数据的代码如下:

scrape_configs:
  # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
  - job_name: 'prometheus'

    # metrics_path defaults to '/metrics'
    # scheme defaults to 'http'.

    static_configs:
    - targets: ['localhost:8080']
           

如上代码表示监控对象的地址是10.10.10.10,端口是8080,Prometheus会周期性地调用这个监控对象(10.10.10.10:8080),但如果服务发生迁移、变更,以及更换地址或者端口,就需要重新修改配置文件并通知Prometheus重新加载配置文件。

为了应对监控对象的变化,Prometheus提供了动态发现方式来获取监控对象

2.动态发现

在云环境下,静态配置方式很难应对云资源动态变化的场景,比如下面两个场景。

  • 动态伸缩场景。根据负载的高低,动态创建或者销毁资源,这里的资源包括虚拟机、容器及关联的资源,这些动态创建的资源很难被运维人员追踪并且加入Prometheus监控或者从监控中剔除。随着DevOps的不断推行,应用不断更新、迭代、上线,一天可能发布多次,每次都可能发布到不同的机器,这都需要一种动态发现机制。
  • 迅速配置场景。在一个Kubernetes集群中可能需要在几分钟内拉起数千个容器,如果需要对每个容器都进行配置,那么工作量可想而知;并且在经过数个小后,这些容器都将被销毁,运维人员可能会崩溃。

    Prometheus通过动态发现方式获取监控对象。目前支持以下系统获取监控对象:

    ◎ 容器管理系统,例如Kubernetes、Marathon;

    ◎ 各种云管平台,例如EC2、Azure、OpenStack;◎ 各种服务发现组件,例如DNS、ZooKeeper和Consul等。

    深入Prometheus设计一 指标含义二 指标分类三 数据采集四 服务发现五 数据处理
    Prometheus 会从这些组件中获取监控对象,并汇总在这些组件中获取的数据,从而获取所有监控对象。在第一次被加入时,监控对象(下称 target)的状态是unknown。之后,Prometheus会在设定的周期内对target数据进行循环采集,如果采集成功,则target状态变为up;如果采集失败(例如超时),则target状态变为down。

五 数据处理

1.数据采集

Prometheus采用统一的Restful API方式获取数据,具体来说是调用HTTP GET请求或metrics数据接口获取监控数据。为了高效地采集数据,Prometheus对每个采集点都启动了一个线程去定时采集数据。在修改了采集的时间间隔后,Prometheus会提供两种配置更新方式:

◎ 第1种是通过调用Prometheus的reload接口进行配置更新;

◎ 第2种是发送信号,通过“kill –HUP Prometheus进程ID”动态加载配置,从而更新采集时间间隔。相较而言,笔者不建议采用第2种配置更新方式,因为它需要动态获取ID。Prometheus 支持文本数据格式,每个 exporter 都将监控数据输出成文本数据格式,文本内容以行(\n)为单位,空行将被忽略,文本内容的最后一行为空行,“#”代表注释,“# HELP”提供帮助信息,“#TYPE”代表 metric类型。

如果是Histogram或Summary类型,则必须满足以下条件:

◎ 指标必须提供sum和count方法,分别表示总和和总量;

◎ Summary类型符合“指标名称{quantile=分位点}”格式;

◎ Histogram类型符合“指标名称_bucket{le=分位点}”格式,必须包含“指标名称_bucket{le="+Inf"}”的指标项,它的值等于“指标名_count”的值;

◎ 在Summary和Historam中,quantile和le必须按从小到大的顺序排列。

2.数据处理

Prometheus会从 target中获取所有暴露的数据,但某些数据对 Prometheus是无用的,如果直接保存这些数据,则不仅浪费空间,还会降低系统的吞吐量。

Prometheus提供了 keep 或 drop 机制,如果设置了 keep 机制,则会保留所有匹配标签的数据;如果设置了drop机制,则会丢弃匹配标签的数据,从而完成数据过滤。除了处理 keep或 drop,Prometheus还支持 Hash的分区采集,通过对 target地址计算 Hash值,然后取模匹配 Prometheus设定的值,便可以过滤该Prometheus负责采集的 target,这也是一种服务端负载均衡的方案,从而扩展 Prometheus的采集能力。

下面是一种通过Hash取模的经典用法

深入Prometheus设计一 指标含义二 指标分类三 数据采集四 服务发现五 数据处理

3.数据存储

(1)本地存储

Prometheus的本地存储经历了两个版本的重要演进,从 Prometheus V1版本升级到V2版本,又升级为现在的V3版本。从V2版本开始,Prometheus的本地存储便充分借鉴了Facebook Gorilla的设计思想及Facebook内部的长期经验,总结了时序数据的以下特点:

◎ 相邻数据点时间戳的差值相对固定,即使有变化,也仅在一个很小的范围内浮动;◎ 相邻数据点的值的变化幅度很小,甚至无变化;

◎ 对热数据的查询频率远远超出对非热点数据的查询频率,并且数据距离现在越近,热度越高。

(2)prometheus V2 与v3 存储的区别

V2

  • 每个序列都有一个文件,这样会耗尽文件系统的Inode,并且同时随机读写了这么多的文件,磁盘的性能会大大降低,对于SSD还会存在写放大的问题。
  • 被监控对象不停更新。例如,在Kubernetes容器监控方面,容器的生命周期比较短暂,指标不停变化,会形成“时序流失”。随着时间的推移,虽然有LevelDB负责时序的索引,但这些时间序列会形成线性增长,导致内存积压过多,

    V3

    ◎ 从 V2版本的每个时序一个文件改进到 V3版本的一段时间一个文件,可以有效避免时序流失的问题,还可以任意组织多个块的数据到一个文件中;

    ◎ 每个文件块最大支持512MB,可避免SSD写放大;

    ◎ 在删除数据的时候更简单,直接删除分区即可;

    ◎ 在查询历史数据时,由于已经按照时间排序,所以可以将内存数据和此磁盘数据合并,通过懒加载的方式载入数据,而不需要将所有磁盘数据加载内存,避免发生OOM。

    (3) 远端存储

    为了提高对大量历史数据持久化存储的能力,Prometheus 在1.6版本后支持远程存储,Adapter需要实现Prometheus的read接口和write接口,并且将read和write转化为每种数据库各自的协议

    深入Prometheus设计一 指标含义二 指标分类三 数据采集四 服务发现五 数据处理
    在用户查询数据时,Prometheus会通过配置的查询接口发送 HTTP请求,查询开始时间、结束时间及指标属性等,Adapter会返回相应的时序数据;相应地,在用户写入数据时,HTTP请求Adapter的消息体会包含时序数组(样本数据)。

4.数据查询

对于Prometheus数据,我们都可以通过HTTP来查询,如果是复杂的数据查询,则还可以使用PromQL进行。和关系型数据库实现SQL解析一样,Prometheus实现了一套自己的数据库语言(PromQL)解析器。PromQL与SQL的最大差别是PromQL只支持查询。

Prometheus 通过解析引擎将查询语句转化为 QUERY 请求,然后通过时序数据库找到具体的数据块,在数据返回后再通过支持内置的函数处理数据,最终将结果返回到前端

深入Prometheus设计一 指标含义二 指标分类三 数据采集四 服务发现五 数据处理

Prometheus支持Grafana等开源显示面板,通过自定义PromQL可以制作丰富的监控视图。Prometheus本身也提供了一个简单的 Web查询控制台,如图2-14所示,Web控制台包含三个主要模块:Graph指标查询,Alerts告警查询、Status状态查询

深入Prometheus设计一 指标含义二 指标分类三 数据采集四 服务发现五 数据处理

继续阅读