Prometheus :(一)基本概念

目录

一:prometheus 概述

1.1什么是 prometheus?

1.2Prometheus的特点

1.2.1 强大的多维度数据模型:

1.2.2 灵活而强大的查询语句(PromQL)

1.2.3 易于管理 

1.2.4 高效的存储

1.2.5 使用 pull 模式采集时间序列数据

1.2.6 可以采用 push gate way 的方式把时间序列数据推送至 Prometheus server 端

1.2.7 可以通过服务发现或者静态配置去获取监控的 targets

1.2.8 有多种可视化图形界面,一般和grafana配合使用

1.2.9 易于伸缩

1.3 什么是样本

1.4 Prometheus局限性

1.5 基本原理

1.6 Prometheus使用场景

二:Prometheus组件介绍

三:prometheus 架构图

四:Prometheus工作流程

五:Prometheus和zabbix对比分析

六:Prometheus的几种部署模式

6.1基本高可用模式

6.2基本高可用+远程存储

6.3基本HA + 远程存储 + 联邦集群方案

七:Prometheus的四种数据类型 

7.1Counter

7.2Gauge

7.3Histogram

7.4Summary

八:Prometheus的存储

8.1存储原理

8.2本地存储 

8.3远程存储 

一:prometheus 概述

1.1什么是 prometheus?

Prometheus是由SoundCloud开发的开源监控报警系统和时序列数据库(TSDB)。Prometheus使用Go语言开发,是Google BorgMon监控系统的开源版本。

Prometheus是一个开源的系统监控和报警系统,2016年由Google发起Linux基金会旗下的原生云基金会(Cloud Native Computing Foundation), 将Prometheus纳入其下,现在已经成为继k8s之后第二大在CNCF托管的项目,在kubernetes容器管理系统中,通常会搭配prometheus进行监控,同时也支持多种exporter采集数据,还支持pushgateway进行数据上报,Prometheus性能足够支撑上万台规模的集群。

1.2Prometheus的特点

作为新一代的监控框架,Prometheus 具有以下特点:

1.2.1 强大的多维度数据模型:

  • 时间序列数据通过 metric (度量指标名称)和标签labels键值对来区分。
  • 所有的 metrics 都可以设置任意的多维标签。
  • 数据模型更随意,不需要刻意设置为以点分隔的字符串。
  • 可以对数据模型进行聚合,切割和切片操作。
  • 支持双精度浮点类型,标签可以设为全 unicode。

每一个时间序列数据都由metric度量指标名称和它的标签labels键值对集合唯一确定:

这个metric度量指标名称指定监控目标系统的测量特征(如:http_requests_total- 接收http请求的总计数)。

labels开启了Prometheus的多维数据模型:对于相同的度量名称,通过不同标签列表的结合, 会形成特定的度量维度实例。(例如:所有包含度量名称为/api/tracks的http请求,打上method=POST的标签,则形成了具体的http请求)。

这个查询语言在这些度量和标签列表的基础上进行过滤和聚合。改变任何度量上的任何标签值,则会形成新的时间序列图。

1.2.2 灵活而强大的查询语句(PromQL)

1.2.3 易于管理 

  •  Prometheus server 是一个单独的二进制文件,可直接在本地工作,不依赖于分布式存储。

1.2.4 高效的存储

  • 平均每个采样点仅占 3.5 bytes,且一个 Prometheus server 可以处理数百万的 metrics。

1.2.5 使用 pull 模式采集时间序列数据

  • 这样不仅有利于本机测试而且可以避免有问题的服务器推送坏的 metrics。

1.2.6 可以采用 push gate way 的方式把时间序列数据推送至 Prometheus server 端

1.2.7 可以通过服务发现或者静态配置去获取监控的 targets

1.2.8 有多种可视化图形界面,一般和grafana配合使用

1.2.9 易于伸缩

1.3 什么是样本

样本:在时间序列中的每一个点称为一个样本(sample),样本由以下三部分组成:

  • 指标(metric):指标名称和描述当前样本特征的 labelsets;
  • 时间戳(timestamp):一个精确到毫秒的时间戳;
  • 样本值(value): 一个 folat64 的浮点型数据表示当前样本的值。

表示方式:通过如下表达方式表示指定指标名称和指定标签集合的时间序列:<metric name>{<label name>=<label value>, ...}

例如,指标名称为 api_http_requests_total,标签为 method="POST" 和 handler="/messages" 的时间序列可以表示为:api_http_requests_total{method="POST", handler="/messages"}

1.4 Prometheus局限性

  • 它的数据是存在内存中的,重启之后和之前的统计全部清零;
  • 每个程序只统计自己的请求次数,如果部署了多个点,则请求得到的统计数据只是单个点的数据,没有做汇总,数据不准确;
  • Prometheus 是基于 指标(Metric)的监控,不适用于日志(Logs)、事件(Event)、调用链(Tracing);它更多地展示的是趋势性监控,而非精准数据;
  • Prometheus 认为只有最近的监控数据才有查询的需要,其本地存储的设计初衷只是保存短期(例如一个月)的数据,因而不支持针对大量的历史数据进行存储,若需要存储长期的历史数据,建议基于远端存储机制将数据保存于 InfluxDB 或 OpenTSDB等系统中
  • Prometheus 的集群机制成熟度不高

1.5 基本原理

Prometheus的基本原理是通过HTTP协议周期性抓取被监控组件的状态,任意组件只要提供对应的HTTP接口就可以接入监控。不需要任何SDK或者其他的集成过程。这样做非常适合做虚拟化环境监控系统,比如VM、Docker、Kubernetes等。输出被监控组件信息的HTTP接口被叫做exporter 。目前互联网公司常用的组件大部分都有exporter可以直接使用,比如Varnish、Haproxy、Nginx、MySQL、Linux系统信息(包括磁盘、内存、CPU、网络等等)。

1.6 Prometheus使用场景

  1. 容器监控,服务部署在云服务器上;
  2. k8s架构下的监控系统;
  3. 急需一套监控系统,而又没有特别大的精力和成本去开发一套;

Prometheus非常适合记录任何纯数字时间序列。它既适合以机器为中心的监视,也适合于高度动态的面向服务的体系结构的监视。在微服务世界中,它对多维数据收集和查询的支持是一种特别的优势。

Prometheus的设计旨在提高可靠性,使其成为中断期间要使用的系统,以使您能够快速诊断问题。

每个Prometheus服务器都是独立的,而不依赖于网络存储或其他远程服务。当基础结构的其他部分损坏时,您可以依靠它,并且无需设置广泛的基础结构即可使用它。


二:Prometheus组件介绍

Prometheus 生态圈中包含了多个组件,其中许多组件是可选的:

(1)Prometheus Server: 用于收集和存储时间序列数据。

(2)Client Library: 客户端库,检测应用程序代码,当Prometheus抓取实例的HTTP端点时,客户端库会将所有跟踪的metrics指标的当前状态发送到prometheus server端。

(3)Exporters:  prometheus支持多种exporter,通过exporter可以采集metrics数据,然后发送到prometheus server端,所有向promtheus server提供监控数据的程序都可以被称为exporter

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

(5)Grafana:监控仪表盘,可视化监控数据

(6)Push Gateway: 各个目标主机可上报数据到pushgateway,然后prometheus server统一从pushgateway拉取数据。

(7)Service Discovery:动态发现待监控的Target,从而完成监控配置的重要组件,在容器化环境尤为有用,该组件目前由 Prometheus Server 内建支持。用户提供的静态资源列表,基于文件的发现,例如,使用配置管理工具生成在Prometheus中自动更新的资源列表,自动发现。


三:prometheus 架构图

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

  • Retrieval 负责在活跃的target主机上抓取监控指标数据
  • Storage 存储主要是把采集到的数据存储到磁盘中
  • PromQL 是Prometheus提供的查询语言模块。

四:Prometheus工作流程

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

注:简单来说,就是收集数据、处理数据、可视化展示,再进行数据分析进行报警处理。

简单介绍:

第一步: Prometheus server定期从配置好的jobs 或者 exporters ,或者从Pushgateway,或者从其他的 Prometheus server 中拉metrics。

  • 默认使用的拉取方式是pull,也可以使用pushgateway提供的push方式获取各个监控节点的数据。

第二步: Prometheus server在本地存储收集到的 metrics,并运行已定义好的alert.rules,通过一定规则进行清理和整理数据,并把得到的结果存储到新的时间序列中。记录新的时间序列或者向Alertmanager推送警报。

  • 获取到的数据存入TSDB,一款时序型数据库。

第三步: Prometheus通过PromQL和其他API可视化地展示收集的数据。Prometheus支持很多方式的图表可视化,

  • 例如Grafana、自带的Promdash以及自身提供的模版引擎等等。
  • Prometheus还提供HTTPAPI的查询方式,自定义所需要的输出。

五:Prometheus和zabbix对比分析

Zabbix Prometheus
后端用 C 开发,界面用 PHP 开发,定制化难度很高。 后端用 golang 开发,前端是 Grafana,JSON 编辑即可解决。定制化难度较低。
集群规模上限为 10000 个节点。 支持更大的集群规模,速度也更快。
更适合监控物理机环境。 更适合云环境的监控,对 OpenStack,Kubernetes 有更好的集成。
监控数据存储在关系型数据库内,如 MySQL,很难从现有数据中扩展维度。 监控数据存储在基于时间序列的数据库内,便于对已有数据进行新的聚合。
安装简单,zabbix-server 一个软件包中包括了所有的服务端功能。 安装相对复杂,监控、告警和界面都分属于不同的组件。
图形化界面比较成熟,界面上基本上能完成全部的配置操作。 界面相对较弱,很多配置需要修改配置文件。
发展时间更长,对于很多监控场景,都有现成的解决方案。 2015 年后开始快速发展,但发展时间较短,成熟度不及 Zabbix。

总结:

如果监控的是物理机,用 Zabbix 没毛病,Zabbix在传统监控系统中,尤其是在服务器相关监控方面,占据绝对优势。甚至环境变动不会很频繁的情况下,Zabbix 也会比 Prometheus 好使;

但如果是云环境的话,除非是 Zabbix 玩的非常溜,可以做各种定制,否则还是 Prometheus 吧,毕竟人家就是干这个的。Prometheus开始成为主导及容器监控方面的标配,与kubernetes适配度更高,并且在未来可见的时间内被广泛应用。如果是刚刚要上监控系统的话,不用犹豫了,Prometheus 准没错。


六:Prometheus的几种部署模式

6.1基本高可用模式

基本的HA模式只能确保Promthues服务的可用性问题,但是不解决Prometheus Server之间的数据一致性问题以及持久化问题(数据丢失后无法恢复),也无法进行动态的扩展。因此这种部署方式适合监控规模不大,Promthues Server也不会频繁发生迁移的情况,并且只需要保存短周期监控数据的场景。

6.2基本高可用+远程存储

在解决了Promthues服务可用性的基础上,同时确保了数据的持久化,当Promthues Server发生宕机或者数据丢失的情况下,可以快速的恢复。 同时Promthues Server可能很好的进行迁移。因此,该方案适用于用户监控规模不大,但是希望能够将监控数据持久化,同时能够确保Promthues Server的可迁移性的场景。

6.3基本HA + 远程存储 + 联邦集群方案

Promthues的性能瓶颈主要在于大量的采集任务,因此用户需要利用Prometheus联邦集群的特性,将不同类型的采集任务划分到不同的Promthues子服务中,从而实现功能分区。例如一个Promthues Server负责采集基础设施相关的监控指标,另外一个Prometheus Server负责采集应用监控指标。再有上层Prometheus Server实现对数据的汇聚。


七:Prometheus的四种数据类型 

7.1Counter

Counter是计数器类型

  • Counter 用于累计值,例如记录请求次数、任务完成数、错误发生次数。
  • 一直增加,不会减少。
  • 重启进程后,会被重置。
# Counter类型示例
http_response_total{method="GET",endpoint="/api/tracks"}  100
http_response_total{method="GET",endpoint="/api/tracks"}  160

Counter 类型数据可以让用户方便的了解事件产生的速率的变化,在PromQL内置的相关操作函数可以提供相应的分析,比如以HTTP应用请求量来进行说明

1)通过rate()函数获取HTTP请求量的增长率:rate(http_requests_total[5m])

2)查询当前系统中,访问量前10的HTTP地址:topk(10, http_requests_total)

7.2Gauge

Gauge是测量器类型

  • 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

7.3Histogram

Histogram作用及特点

histogram是柱状图,在Prometheus系统的查询语言中,有三种作用:

1)在一段时间范围内对数据进行采样(通常是请求持续时间或响应大小等),并将其计入可配置的存储桶(bucket)中. 后续可通过指定区间筛选样本,也可以统计样本总数,最后一般将数据展示为直方图。

2)对每个采样点值累计和(sum)

3)对采样点的次数累计和(count)

度量指标名称: [basename]上面三类的作用度量指标名称

1)[basename]bucket{le="上边界"}, 这个值为小于等于上边界的所有采样点数量
2)[basename]_sum_
3)[basename]_count

注:如果定义一个度量类型为Histogram,则Prometheus会自动生成三个对应的指标

为什需要用histogram柱状图?

在大多数情况下人们都倾向于使用某些量化指标的平均值,例如 CPU 的平均使用率、页面的平均响应时间。这种方式的问题很明显,以系统 API 调用的平均响应时间为例:如果大多数 API 请求都维持在 100ms 的响应时间范围内,而个别请求的响应时间需要 5s,那么就会导致某些 WEB 页面的响应时间落到中位数的情况,而这种现象被称为长尾问题。

​ 为了区分是平均的慢还是长尾的慢,最简单的方式就是按照请求延迟的范围进行分组。例如,统计延迟在 0~10ms 之间的请求数有多少,而 10~20ms 之间的请求数又有多少。通过这种方式可以快速分析系统慢的原因。Histogram 和 Summary 都是为了能够解决这样问题的存在,通过 Histogram 和 Summary 类型的监控指标,我们可以快速了解监控样本的分布情况。

Histogram 类型的样本会提供三种指标(假设指标名称为 <basename>):

1)样本的值分布在 bucket 中的数量,命名为 <basename>_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

2)所有样本值的大小总和,命名为 <basename>_sum

# 实际含义: 发生的2次 http 请求总的响应时间为 13.107670803000001 秒
io_namespace_http_requests_latency_seconds_histogram_sum{path="/",method="GET",code="200",} 13.107670803000001

3)样本总数,命名为 <basename>_count,值和 <basename>_bucket{le="+Inf"} 相同

# 实际含义: 当前一共发生了 2 次 http 请求
io_namespace_http_requests_latency_seconds_histogram_count{path="/",method="GET",code="200",} 2.0

注意

1)bucket 可以理解为是对数据指标值域的一个划分,划分的依据应该基于数据值的分布。注意后面的采样点是包含前面的采样点的,假设 xxx_bucket{...,le="0.01"} 的值为 10,而 xxx_bucket{...,le="0.05"} 的值为 30,那么意味着这 30 个采样点中,有 10 个是小于 0.01s的,其余 20 个采样点的响应时间是介于0.01s 和 0.05s之间的。

2)可以通过 histogram_quantile() 函数来计算 Histogram 类型样本的分位数。分位数可能不太好理解,你可以理解为分割数据的点。我举个例子,假设样本的 9 分位数(quantile=0.9)的值为 x,即表示小于 x 的采样值的数量占总体采样值的 90%。Histogram 还可以用来计算应用性能指标值(Apdex score)。

7.4Summary

与 Histogram 类型类似,用于表示一段时间内的数据采样结果(通常是请求持续时间或响应大小等),但它直接存储了分位数(通过客户端计算,然后展示出来),而不是通过区间来计算。它也有三种作用:

1)对于每个采样点进行统计,并形成分位图。(如:正态分布一样,统计低于60分不及格的同学比例,统计低于80分的同学比例,统计低于95分的同学比例)

2)统计班上所有同学的总成绩(sum)

3)统计班上同学的考试总人数(count)

带有度量指标的[basename]的summary 在抓取时间序列数据有如命名。

1、观察时间的φ-quantiles (0 ≤ φ ≤ 1), 显示为[basename]{分位数="[φ]"}

2、[basename]_sum, 是指所有观察值的总和_

3、[basename]_count, 是指已观察到的事件计数值

样本值的分位数分布情况,命名为 <basename>{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

所有样本值的大小总和,命名为 <basename>_sum

# 1、含义:这12次 http 请求的总响应时间为 51.029495508s
io_namespace_http_requests_latency_seconds_summary_sum{path="/",method="GET",code="200",} 51.029495508

样本总数,命名为 <basename>_count

# 1、含义:当前一共发生了 12 次 http 请求
io_namespace_http_requests_latency_seconds_summary_count{path="/",method="GET",code="200",} 12.0

Histogram 与 Summary 的异同

它们都包含了 <basename>_sum 和 <basename>_count 指标,Histogram 需要通过 <basename>_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。

八:Prometheus的存储

8.1存储原理

1、prometheus 提供了本地存储(TSDB)时序型数据库的存储方式,在2.0版本之后,压缩数据的能力得到了大大的提升,单节点情况下可以满足大部分用户的需求,但本地存储阻碍了prometheus集群化的实现,因此在集群中应当采用 其他时序性数据来替代,比如influxdb。

2、prometheus按照block块的方式来存储数据,每2小时为一个时间单位,首先会存储到内存中,当到达2小时后,会自动写入磁盘中。

3、为防止程序异常而导致数据丢失,采用了WAL机制,即2小时内记录的数据存储在内存中的同时,还会记录一份日志,存储在block下的wal目录中。当程序再次启动时,会将wal目录中的数据写入对应的block中,从而达到恢复数据的效果。

8.2本地存储 

会直接保留到本地磁盘,性能上建议使用SSD且不要保存超过一个月的数据。记住,任何版本的Prometheus都不支持NFS。一些实际生产案例告诉我们,Prometheus存储文件如果使用NFS,则有损坏或丢失历史数据的可能。

8.3远程存储 

适用于存储大量的监控数据。Prometheus支持的远程存储包括OpenTSDB、InfluxDB、Elasticsearch、Kakfa、PostgreSQL等。远程存储需要配合中间层的适配器进行转换,主要涉及Prometheus中的remote_write和remote_read接口。在实际生产中,远程存储会出现各种各样的问题,需要不断地进行优化、压测、架构改造甚至重写上传数据逻辑的模块等工作。

猜你喜欢

转载自blog.csdn.net/ver_mouth__/article/details/126269699