Prometheus基本概述

官网:https://prometheus.io/

prometheus github社区:https://github.com/prometheus-community/

【1】基本介绍

【1.0】Prometheus 与 其他监控产品的优劣

优点:

  (1)监控数据的精细程度非常高,可以精确到1-5秒的采集精度

  (2)软件的部署非常快,大大缩减搭建时间成本

  (3)周边插件很丰富,比如 exporter pushgateway 大多数都步需要自己开发了

  (4)基于数学计算模型(proMQL),大量的使用函数,可以实现很复杂规则的业务逻辑监控(比如QPS曲线,弯曲,凸起,下跌,比例等等模糊)

  (5)可以嵌入很多开源工具的内部,比如nignx 、数据库 等,进行监控,数据更准时更可信(其他监控比较难做到)

  (6)结合grafana 图形很高大上很美观

不足:

  (1)因为图形菜鸡经度,如果集群数据量太大,那么简单监控有性能瓶颈。

  (2)学习成本大,还有 proMQL,中文资料极少,没有人教 官网英文资料也是比较难入门

  (3)对磁盘资源消耗比较大,这个具体要看监控的集群数量 和 监控项的多少 以及保存时长的设置

  (4)本身的使用,需要使用者数学不能太差,有一定的数据逻辑

【1.1】概念及特点

简介:

  Prometheus是一个最初在SoundCloud上构建的开源系统监控和警报工具包 。自2012年成立以来,许多公司和组织都采用 Prometheus,该项目拥有非常活跃的开发人员和用户社区。

  它现在是一个独立的开源项目,并且独立于任何公司。为了强调这一点,并澄清 项目的治理结构,Prometheus 于2016年加入 云本地计算基金会,作为Kubernetes之后的第二个托管项目。

特点:

  Prometheus 属于一站式监控告警平台,依赖少,功能齐全。 Prometheus 支持对云的或容器的监控,其他系统主要对主机监控。

   Prometheus 数据查询语句表现力更强大,内置更强大的统计函数。 Prometheus 在数据存储扩展性以及持久性上没有 InfluxDB,OpenTSDB,Sensu 好。

优质特性:

(1)基于 time series 时序模型,既使用时序数据库存储模型。什么是时序序列呢?就是(x,y)轴,x为时间,y为值

(2)使用 K/V 的数据模型,格式简单,速度快,易维护开发

(3)采样数据查询:promQL,比如可以 (增量A+增量B)/ 总量C

(4)采用 HTTP pull /push 两种对应的数据采集方式传输

(5)【开源,及大量插件】

(6)【本身自带挺调试】、【秒级数据采样频率,秒级采样间隔】

(7)通过服务发现或者静态配置,来发现目标服务对象

(8)不依赖分布式存储,单个服务器节点是自主的

 

不足:

(1)本身不支持集群化

(2)被监控集群过大后,本身可能会产生性能瓶颈

(3)中文支持不好,中文资料也少

【1.2】prometheus 基本组件

  1. Prometheus Server, 主要用于抓取数据和存储时序数据,另外还提供查询和 Alert Rule 配置管理。
  2. client libraries,用于对接 Prometheus Server, 可以查询和上报数据。
  3. push gateway ,用于批量,短期的监控数据的汇总节点,主要用于业务数据汇报等。
  4. 各种汇报数据的 exporters ,例如汇报机器数据的 node_exporter, 汇报 MongoDB 信息的 MongoDB exporter 等等。
  5. 用于告警通知管理的 alertmanager 。

【1.3】基本原理

  Prometheus基本原理是通过HTTP协议周期性抓取被监控组件的状态,这样做的好处是任意组件只要提供HTTP接口就可以接入监控系统, 不需要任何SDK或者其他的集成过程。

  这样做非常适合虚拟化环境比如VM或者Docker 。 Prometheus应该是为数不多的适合Docker、Mesos、Kubernetes环境的监控系统之一。

  输出被监控组件信息的HTTP接口被叫做exporter 。

  目前互联网公司常用的组件大部分都有exporter可以直接使用,比如Varnish、 Haproxy、Nginx、MySQL、Linux 系统信息 (包括磁盘、内存、CPU、网络等等)

【1.4】监控的基本体系流程

  

【2】认识prometheus

【2.1】基本架构与模块

      

 

 

 

  从这个架构图,也可以看出 Prometheus 的主要模块包含, Server, Exporters, Pushgateway, PromQL, Alertmanager, WebUI 等。

【2.2】Promethues server 模块

  

prometheus 本身是一个以进程方式启动,之后以多进程和多线程实现监控数据收集、计算、查询、更新、存储的CS模型运行模式

默认为9090端口。

一、存储模块

(1)时序数据库 tsdb 存储

(2)TS格式以每2个小时间隔来分 block,每一个块中又分为多个 chunk文件,chunk文件使用来存放 才寄过来的T-S数据,metadate和索引文件

(3)index文件,是对 metrics/prometheus 中 一次K/V菜鸡数据叫做一个 metric 和 labels(标签) 进行索引之后存储在chunk中,chunk是作为存储的基本单位,index and metadate 是作为自己。

(4)prometheus 平时是将才寄过来的数据 先都存放在内存中(prometheus对内存的消耗 还是不小的),以类似缓存的方式用于加快搜索和访问

(5)当出现宕机时,prometheus 有一种保护机制,叫做 WAL(预写式日志),可以将数据定期存入硬盘中,以chunk来表示,并在重启时 用以恢复数据进入内存

二、http server

(1)有用http服务器,以便可以web页面访问,以及web方式 pull ;

【2.3】 service discovery(服务发现)

  

 

 

也就是自动把节点发现到 prometheus,而不是都需要手动配置 prometheus.yml  配置文件

【2.4】pull metrics(拉取监控指标信息)

  

 

 

(1)pull 主动拉取形式

pull:指定是客户端(被监控的机器)先安装各类已用的 采集器 ,比如 node_exporters (linux服务器采集器),之后exporters 以守护进程的方式运行 并开始采集数据。

         同时 exporter 本身也是一个 http_server,可以对 http 请求做出响应,返回数据(K/V metrics),所以服务端才能以http的方式 pull 客户端的指标信息

(2)push

其实这里就涉及到一个 pushgateway,这个东西类似于一个中转站一样。安装好之后。

客户端的相关job push数据(以K/V metrics形式)到 pushgateway(即客户端主动发送数据到pushgateway),然后 pushgateway  push 数据到 prometheus 服务器中去。

这是一种被动的数据模式。

 

【2.5】Alertmanager 监控

  

 

prometheus 服务器把报警信息=》 Alertmanager=》实际报警信息发送

 

【2.6】数据可视化界面 

    

 

 web界面 现在用的最多的是 Grafanna.

 

【3】prometheus 监控数据格式

【3.1】Metrics数据类型(Gauges,Counter,Histograms,Summary

prometheus 监控中,对于采集过来的数据,统一称为 metics数据

metrics 是一种对采集数据的总称(metrics 并不代表某一种具体的数据格式,是一种对于度量单位和采集样本的抽象描述)

 

它分为以下4种类型

(1)Gauge 类型,瞬态值

最简单的度量指标,只有一个简单的返回值,或者叫瞬时状态,这个值是随机、无规律的。

例如:

  我们要监控硬盘容量或者内存使用量,那么就应该使用 Gauges 的 metrics 格式来度量。采集到当前值是多少就是多少

因为内存、硬盘容量的使用情况  是随着时间的推移 不断的随机的瞬时的没有规则的变化;(比如内存分配、内存释放等无规律的操作.....)

CPU也是这样。

采集数据样例图:

  

 

 

(2)Counter 类型,累计值

Counter 就是计数器,从数据量0开始累积计算,在理想状态下 该值数据是永远增长的,不会降低(一些特殊情况另说)

举例:

  对用户访问量的采样数据,访问量是只会增不会减的。

特例,特殊情况:

  比如我每天晚上 2点 对访问量做清理操作,这就另说了。

采集数据样例图:

  

 

 

(3)Histograms,直方图

参考:https://blog.csdn.net/j3T9Z7H/article/details/99503789

参考:https://zhuanlan.zhihu.com/p/104607739

翻译过来大概是:比例型的估算数值

histogram 统计数据的分部情况。比如最小值,最大值,中间值,中位数,75百分位,90百分位,95/98/99/99.9百分位的值(percentlies)

这是一种特殊的 metrics 数据类型,代表的是一种 近似的百分比估算值

假设描述:

  假设我们想监控某个应用在一段时间内的响应时间,最后监控到的样本的响应时间范围为 0s~10s。

  现在我们将样本的值域划分为不同的区间,即不同的 bucket,每个 bucket 的宽度是 0.2s。

  那么第一个 bucket 表示响应时间小于等于 0.2s 的请求数量,第二个 bucket 表示响应时间大于 0.2s 小于等于 0.4s 的请求数量,以此类推。

Prometheus 的 histogram 是一种累积直方图,与上面的区间划分方式是有差别的,它的划分方式如下:

  还假设每个 bucket 的宽度是 0.2s,那么第一个 bucket 表示响应时间小于等于 0.2s 的请求数量,第二个 bucket 表示响应时间小于等于 0.4s 的请求数量,以此类推。

  也就是说,每一个 bucket 的样本包含了之前所有 bucket 的样本,所以叫累积直方图。

问题 1:P99 可能比平均值小吗?

正如中位数可能比平均数大也可能比平均数小,P99 比平均值小也是完全有可能的。

通常情况下 P99 几乎总是比平均值要大的,但是如果数据分布比较极端,最大的 1% 可能大得离谱从而拉高了平均值。

一种可能的例子:

  1, 1, ... 1, 901 // 共 100 条数据,平均值=10,P99=1

 

histogram 场景下的 quantile

前面的内容都是从 quantile 的定义出发的,并不限于 Prometheus 平台。具体针对 Prometheus 里的 histogram_quantile,还有一些要注意的点。

  一个是因为 histogram 并不记录所有数据,只记录每个 bucket 下的 count 和 sum。

如果 bucket 设置的不合理,会产生不符合预期的 quantile 结果。

比如最大 bucket 设置的过小,实际上有大量的数据超出最大 bucket 的范围,最后统计 quantile 也只会得到最大 bucket 的值。

  因此如果观察到 histogram_quantile 曲线是笔直的水平线,很可能就是 bucket 设置不合理了。

另一种情况是 bucket 范围过大,绝大多数记录都落在同一个 bucket 里的一段小区间,也会导致较大的偏差。

  例如 bucket 是 100ms ~ 1000ms,而大部分记录都在 100ms ~ 200ms 之间,计算 P99 会得到接近于 1000ms 的值,这是因为 Prometheus 没记录具体数值,便假定数据在整个 bucket 内均匀分布进行计算。

  Prometheus 的官方文档 里也描述了这个问题。

【案例】函数,histogram_quantile(histogram类型值)

比如某个直方图的

# TYPE etcd_disk_wal_fsync_duration_seconds histogram
etcd_disk_wal_fsync_duration_seconds_bucket{le="0.001"} 78
etcd_disk_wal_fsync_duration_seconds_bucket{le="0.002"} 81
etcd_disk_wal_fsync_duration_seconds_bucket{le="0.004"} 83
etcd_disk_wal_fsync_duration_seconds_bucket{le="0.008"} 83
etcd_disk_wal_fsync_duration_seconds_bucket{le="0.016"} 87
etcd_disk_wal_fsync_duration_seconds_bucket{le="0.032"} 91
etcd_disk_wal_fsync_duration_seconds_bucket{le="0.064"} 98
etcd_disk_wal_fsync_duration_seconds_bucket{le="0.128"} 99
etcd_disk_wal_fsync_duration_seconds_bucket{le="0.256"} 100
etcd_disk_wal_fsync_duration_seconds_bucket{le="0.512"} 100
etcd_disk_wal_fsync_duration_seconds_bucket{le="1.024"} 100
etcd_disk_wal_fsync_duration_seconds_bucket{le="2.048"} 100
etcd_disk_wal_fsync_duration_seconds_bucket{le="4.096"} 100
etcd_disk_wal_fsync_duration_seconds_bucket{le="8.192"} 100
etcd_disk_wal_fsync_duration_seconds_bucket{le="+Inf"} 100
etcd_disk_wal_fsync_duration_seconds_sum 0.654113336
etcd_disk_wal_fsync_duration_seconds_count 100

histogram_quantile(1,etcd_disk_wal_fsync_duration_seconds_bucket{instance="192.168.148.39:2379",job="etcd_cluster",name="etcd-1"})

  查询p100,对应 bucket 的 0.256,就表示所有的命中都在 0.256(后续再累计也只有100个了)

histogram_quantile(0.91,etcd_disk_wal_fsync_duration_seconds_bucket{instance="192.168.148.39:2379",job="etcd_cluster",name="etcd-1"})

  查询p91,就是结果是 0.032,如上面直方图数据,91 正好对应 bucket 0.032;

histogram_quantile(0.90,etcd_disk_wal_fsync_duration_seconds_bucket{instance="192.168.148.39:2379",job="etcd_cluster",name="etcd-1"})

  查询p90,结果是0.028 =》怎么得出的呢?那么我们根据上面2个可以分析出,

    p91是0.032,p87是0.016 ,那么 91-87=4,正好 p91的0.032-p87的0.016=0.016

    那么0.016/4=0.004,所以对于此时 p91~p97之间,每一个p1对应差值为 0.004;自然然而 p90 就是 p91的值 0.032-0.004=0.028;

(4)Summary

  Summary和Histogram十分相似,常用于跟踪事件发生的规模,例如:请求耗时、响应大小。同样提供 count 和 sum 全部值的功能。

  例如:count=7次,sum=7次的值求值。 它提供一个quantiles的功能,可以按%比划分跟踪的结果。例如:quantile取值0.95,表示取采样值里面的95%数据。

【3.2】metrics K/V数据

我们在node_exporter 节点运行URL 访问

 curl http://localhost:9100/metrics

我们可以清楚的看到其返回类型

# TYPE process_cpu_seconds_total counter
process_cpu_seconds_total 357.94
# HELP process_max_fds Maximum number of open file descriptors.
# TYPE process_max_fds gauge
process_max_fds 1024
# HELP process_open_fds Number of open file descriptors.
# TYPE process_open_fds gauge
process_open_fds 10

如上面代码,我们可以看到 会有注释 显示 type,是gauge 还是 counter 等等

process_open_fds 10

这就表示  Key 是  process_open_fds   Value 是  10


【4】pushgateway

【4.1】基本介绍

push的形式是把 pushgateway 安装在 客户端或者服务器端(其实都可以)

它本身也是一个http服务器

运维通过写自己的脚本程序,抓自己想要的监控数据,转换成 K/V 的形式,然后推送到 Pushgateway(HTTP POST) 再由 Pushgateway 推送到 Prometheus 服务器端

【4.2】exporter已经很丰富了,为什么还要 pushgateway?

(1)exporter 虽然采集很多数据,但是我们依然需要很多自制的监控数据,非规则化,自定制的

(2)exporter 由于数据类型采集量太大,其实很多数据 甚至对大部分数据都用不到,用pushgateway 是定义一项或者几项数据,节约资源。

(3)一个新的自定义的 pushgateway 脚本开发,比开发一个新的 exporter 简单快速的多的多的多!

  (exporter 需要真正的变成语言,shell 之类的是不行的,而且exporter 还需要了解很多 prometheus自定的变成格式才能开始制作,工作量巨大)

(4)exporter 虽然已经很丰富了,但是依然有很多我们需要的采集形式,exporter无法提供,或者说现有的 exporter 还不支持,但是如果使用 pushgateway 的形式,就可以非常灵活 想采集什么样的都可以,而且极快。

【4.3】图解 pushgateway 和 常规 exporter 的流程形式

  

【5】UI界面上的 Status

(5.1)运行时状态

  

 

 包含:下面模块

  • Alertmanagers
  • Head Stats
  • Highest Cardinality Labels
  • Highest Cardinality Metric Names
  • Label Names With Highest Cumulative Label Value Length
  • Most Common Label Pairs

(5.2)命令行参数、标签

  

 

(5.3)配置文件、当前生效配置

  

 

(5.4)当前生效的 rule 规则

  

 

(5.5)targets 对象

查看当前配置实例服务器的状态

  

 

(5.6)服务发现总览

  

 

(5.7)UI界面上的 Alert

  

• Inactive:这里什么都没有发生。

• Pending:已触发阈值,但未满足告警持续时间

• Firing:已触发阈值且满足告警持续时间。警报发送给接受者

   

【默认端口】

服务器端:

   prometheus:        9090

   node_exporter:    9100

   mysqld_exporter:9104

 Alertmanager:    9093

   wmi-exporter:     9182

【告警模板】

【email】

 {{ define "email.default.message" }}
{{- if gt (len .Alerts.Firing) 0 -}}{{ range $i, $alert :=.Alerts }}
{{- if eq $alert.Labels.severity "紧急" }}
========紧急告警==========<br>
{{- else }}
========监控告警==========<br>
{{- end }}
告警主机:{{ $alert.Labels.host_label }}<br>
告警级别:{{ $alert.Labels.severity }}<br>
告警状态:{{   .Status }}<br>
告警类型:{{ $alert.Labels.alertname }}<br>
告警概述:{{ $alert.Annotations.summary }}<br>
告警取值:{{ $alert.Annotations.value }}<br>
告警时间:{{ ($alert.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}<br>
运营团队: {{ $alert.Labels.team }}<br>
告警详情:{{ $alert.Annotations.description }}<br>
========end=============
{{ end }}
{{ end -}}
{{- if gt (len .Alerts.Resolved) 0 -}}{{ range $i, $alert :=.Alerts }}
====告警恢复=====<br>
告警主机:{{ $alert.Labels.host_label }}<br>
告警状态:{{   .Status }}<br>
告警类型:{{ $alert.Labels.alertname }}<br>
告警概述:{{ $alert.Annotations.summary }}-->恢复<br>
告警时间:{{ ($alert.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}<br>
恢复时间:{{ ($alert.EndsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}<br>
========end=============
{{ end }}
{{ end -}}
{{ end }} 
 

【学习参考文档】

posted @ 2020-08-07 18:11  郭大侠1  阅读(1847)  评论(0编辑  收藏  举报