Prometheus简介
理论来源:2、监控系统基础应用
Prometheus创始者,是Google出来的一个员工,但他后来到SoundCloud工作了,当他就职SoundCloud之后模仿Google的监控BorgMon,也就是Borg的监控系统(Kubernetes的前身),开发了Prometheus监控系统,所以说Prometheus更加适用于Kubernetes的,因为它从设计上,就有了这样的考虑,其实Prometheus到今天为止已经出现很多年了,2012年就开始研发了,只不过2015年才发布出来,2016年五月份,加入了CNCF,所以它也是云原生基金会的产品之一,差不多在2016年6月份发布1.0版,到今为止已经达到2.x系列;一款主要用于提供近实时的、基于动态云环境和容器的微服务、服务和应用程序的内省监控
一、 特点
Prometheus本身它有几个比较显著的特点,才使得其这么流行如当下
- 它的时间序列数据,通常都是统统称之为Metric
- Prometheus数据格式,Prometheus格式对于指标数据的格式也有了自己的定义,有了自己独创的指标格式,我们称其为Prometheus格式,Prometheus格式到今天已经是非常非常流行了,以致于大量的开发的新的程序,或者传统程序在版本迭代时,都会内置一些监控指标,这种指标的格式就是Prometheus格式的Metric;
- 多纬度的标签,它这个Metric有一个非常大的特点,就是支持多纬度的标签,而且每个独立的标签组合,都代表一个独立的时间序列的样本数据,它的数据模型非常的随意,不想SqlServer或者像MySQL这样的,事先定义好表结构,而Prometheus在一个对应的指标上,添加一个标签,并且标签增删随意;
- 数据处理,Prometheus也可以对我们的时序数据做聚合、切割、切片,它内置了这种各种高级操作机制;
- 支持双精度浮点型数据,因此Prometheus所能表达的数据的能力更加的但是,它也有缺点,Prometheus所存储的样本数据都是双精度浮点型数据,所以它就不能存储文本,所以它没办法去采集日志然后给它存储下来,Zabbix是可以存日志的;
二、工作原理
- Prometheus是一款时序数据库,它自己就直接带了存储引擎,它又带了数据抓取器(exporter),而且它把数据抓取过来之后就把数据存储在自己内建的时序数据库当中,但是它的功能并非止步于时序存储,而是专门用于实现目标监控的一个关键组件,因为它带有采集器,而且这个采集器有很灵活、高效的可配置能力;
- prometheus通过抓取或拉取应用程序中暴露的时间序列数据来工作,时间序列数据通常由应用程序本身通过客户端或称为 exporter(导出器)的代理来作为http端点暴露
- 因而,从某种意义上来讲,它的监控能力才是根本,时序存储反倒是为了监控的存储而特别设计的,但话又说出来,它但时序存储默认保存数据的时长是有限的,默认是一个月,如果我们要想保存更长时期的历史数据,使用它内建的时序数据库就不行了,我们需要对接远程存储系统,比如InfluxDB或者OpenTSDB都可以,很多人都在使用InfluxDB这样都存储系统,我们可以对接到Prometheus上,让它作为Prometheus长期存储监控数据的存储后端;
- Prometheus内建插件支持多种存储系统,所以说,Prometheus要想能够完整的工作起来,并且长期存储数据,需要对接的生态组件非常的多,除了上述的外部存储之外还包括很多组件,比如PushGateway、AlterManager和Grafana等,就可构成一个完整意义上的IT监控系统;
- 总结:Prometheus内置了存储能力,又内置了数据采集器,而且它的采集是工作于Pull模式;
三、数据采集模型
数据采集模型一般有两种:pull\push
- pull:由监控系统自己主动的联系被监控端,主动取回数据
- push: 被监控端主动联系监控系统,提交自己的指标数据
Prometheus工作于pull模式,如果不在服务端上定义好要取的数据,它是一定不会拉取的,如果prometheus要实现push的话,就不得不借助于另外一个系统,来帮忙接收别人push的数据,这个组件就是PushGateway,而我们的Prometheus 会定时去向PushGateway去pull数据,这样我们的Prometheus 就不直接到被监控端去拉去数据了,直接在PushGateway端拉取数据即可,仍然工作于拉取模式;
3.1、PromQL
Prometheus 内建有一个非常强大的查询接口,就像MySQL的SQL引擎一样,可以使用SQL语句就能完成数据处理了,Prometheus这个内建的查询引擎同样提供了一个类SQL语句一样的接口,只不过它不叫SQL,而是PromQL,我们要给它传递就的Prometheus的查询表达式,这也是Prometheus的最主要的核心功能之一;
- PromQL支持用户进行实时针对Prometheus存储下来的数据做查询或者聚合操作,因而Prometheus会周期性的采集数据,每一个数据都会存下来,存的时候每个数据其实都是K/V型的数据,它的K就是它所属时间序列的标识,V就是样本值;
- 而后,我们想看某一个特定的时序样本值的时候,我们就需要基于这些K做过滤,整个K由指标名称和标签组成,于是我们可以针对指标名称做过滤,也可以针对标签做过滤,那么这个时候PromQL就是针对K所描述出来的查询表达条件,这个表达条件既可以基于K,做过滤,也可以基于标签做过滤;
- 因此我们对应的数据在其内部,所查询出来的结果,可能有多种数据类型,比如有常量,有向量,所谓向量就是带方向的数据,在PromQL有两种向量,
- 第一是即时向量
- 第二种是时间范围向量
3.2、AlterManager
Prometheus自己能够出发报警,但是它不会发送报警,比如我们使用PromQL的布尔表达判定一下,判定这个数据是否符合我们的期望,如果不符合,我们采取什么措施,所以Prometheus还得再对接一个组件,即AlterManager,它就是一个查询报警器,它就是根据PromQL定义的查询表达式实现告警的;
比如说,只要我们定义了监控规则,如果这个监控规则触发了,需要报警的时候,那么它就会送给AlterManager,由AlterManager借助于邮件、微信、叮叮等发送告警给用户,所以说Prometheus由两部分组成,Prometheus只是产生告警,真正告警发送说由我们AlterManager实现的;
3.3、Exporter
prometheus称其可以抓取的指标来源为 端点(endpoint), 端点通常对应单个进程、主机、服务或应用程序,
- 为了抓取端点数据,prometheus定义了名为目标(target)的配置。这是执行抓取所需的信息,如:如何进行连接,要应用哪些元数据,连接需要哪些身份验证,或者定义抓取将如何执行其它信息,
- 一组目标被称为作业(job), 作业通常是具有相同角色的目标组,如HA后面的apach服务器集群,它们实际上是一组相似的进程
- 比如我们有四个MySQL需要监控,那么一个指标暴露器只能对接一个MySQL,所以从某种意义上来讲我们可以理解这个Exporter为指标抓取代理器,Prometheus有很多指标暴露器,同时我们也自己开发一个指标暴露器,几行代码就能做到;
四、数据处理
4.1、时序数据
- 时序数据其实就是在一段时间内,通过反复侧量而获得的观测值的集合,这些集合是按照固定时间周期串联起来的,如果将这些观测值绘制在一个图形之上,它会有一个数据轴和时间轴,如下图,但是实际上我们采样的数据并非都是连续的,只不过绘制的图都链成了一个线了;
- 对于监控系统来讲,服务器的指标数据库、应用的性能监控数据、网络负载数据等都是时序数据,因为Prometheus抓出来的数据也都是时序数据;
4.2、数据抓取
整个Promethues的监控生态当中,Prometheus是核心,它有四个核心组件,第一scrape用于数据采集,第二TSDB用于时序数据存储,第三ProQL数据查询,第四Server Discovery服务发现;
其中scrape是基于HTTP协议来实现的,这也就意味着每个待被抓取的指标,暴露服务必须是HTTP协议,在Prometheus当中,所有的数据抓取都是以pull模式抓取的,而且每一个生成指标数据的被采集段在Prometheus的语境当中被称作Target,这个Target指的实际上就是一个网络端点,一个IP+端口,如果对于HTTP协议而言,它还可能会有一个URL,而这个URL对于Prometheus而言,固定称谓为Metrics;
那么很显然,Target可能有很多个,而Metrics可能会更多,而它的抓取操作是根据Http call实现的,这就是为什么我们就不得不在被监控端安装一个expoter的原因;
Prometheus支持三种类型的途径从目标上“抓取(Scrape)”,第一种是Exporter,它就是一个HTTP的指标暴露器,第二Instrumentation这就是应用程序内建的测量系统,当然,还是通过HTTP协议暴露指标,第三pushgateway,无论是哪一种方式,对于Prometheus都是pull metrics;
五、Prometheus生态组件
Prometheus生态圈中包含了多个组件,其中部分组件可选;
- Prometheus Server:收集和存储时间序列数据;
- Client Library:客户端库,目的在于为那些期望原生提供Instrumentation功能的应用程序提供便捷的开发途径;
- Push Gateway:接收哪些通常由短期作业生成的指标数据的网关,并支持由Prometheus Server进行拉取操作;
- Exporters:用于暴露现有应用程序或服务(不支持Instrumentation的)的指标给Prometheus Server;
- AlterManager:从Prometheus Server接收到告警通知后,通过去重、分组、路由等预处理功能后以高效向用户完成告警信息发送;
- **Data Visualization:**Prometheus WebUI;
- Server Discovery:动态发现待监控的Target,从而完成监控配置的重要组件,在容器化环境尤为有用;
六、prometheus数据模型
- 对于Prometheus而言,我们需要去以抓取的方式到每个Target上抓取可能不止一个时序数据,每一个指标纬度就会生成一个或多个时间序列,对于CPU这一个指标来讲,它可能就有多个指标纬度;
- 比如定义一个指标为CPU_USAGE,但是对于CPU而言可能有多个纬度的使用率,比如内核空间的使用率,用户空间使用率,因此CPU_USAGE指标虽然是一个使用率指标,但它是一个统称指标;
- 我们需要在他们背后附加很多标签,从而代表不同的序列,所以一个指标可能会生成N个时间序列,其实可以将一个指标想像成MySQL中的一个表,但这个表中有很多数据项,而标签则是where语句后面的过滤表达式;
- Prometheus仅用于以“键值”形式存储时序式的聚合数据,它并不支持存储文本信息,其中“键”称之为Metrics,它通常意味着CPU的速率、内存使用率或者分区空闲比例等,同一个指标可能会适配到多个目标或设备,因而它使用“标签”作为元数据,使得Metric能够添加更多的信息描述纬度,这些标签还可以作为过滤器进行指标过滤及聚合运算;
6.1、标签
Label就是键/值形式的标签,并且新的标签会创建新的时间序列, 带有__前缀的标签名称保留给prometheus内部使用
标签为prometheus数据模型提供了维度,它们为特定时间序列添加上下文,例如 total_website_visits时间序列可以使用能够识别网站名称、请求IP和其它特殊标识的标签
- 标签共有两大类: 插桩标签和目标标签
- 插桩标签: 来自被监控的资源,如:对于HTTP相关的时间序列,标签可能会显示所使用的特定HTTP动词,这些标签在由诸如客户端或exporter抓取之前会被添加到时间序列中
- 目标标签:与架构相关,它们会识别时间序列所在的数据中心,目标标签由prometheus在抓取期间和之后添加
6.2、指标
在Prometheus当中,在存指标数据的时,指标也有类型的概念,指标类型不是数据类型,而数据类型都是以双精度浮点的,指标类型指的是,存储双精度浮点数据是以什么方式存储的,常见指标类型如下;
6.2.1、什么是指标
指标是软件或硬件组件属性的度量,为了使指标有价值,我们会跟踪其状态,通常记录一段时间的数据点,这些数据点称为 观察点,它通常包括 值、时间戳,有时也涵盖描述观察点的一系列属性(源或标签),观察的集合称为时间序列
6.2.2、指标类型
- 测量型: 这种类型是上下增减的数字,本质上是特定度量的快照,常见的监控指标如CPU、磁盘使用率和内存属于这个类型,对业务指标来说则是网站上的客户数量;
- 计数型: 随着时间增加而不会减少的数字,虽然它们永远不会减少,但有时将其重置为零并再次开始递增,应用程序和基础设施的计数型示例包括系统正常运行时间、设备收发包的字节数或登陆次数, 而业务的示例可能是 一个月内的销售数量或应用程序收到的订单数量
- 直方图: 是对观察点进行采样的指标类型,可以展现数据集的频率分布,直方图可以很好的展现时间序列数据,尤其是数据的可视化(如应用程序的延时)
七、demo
通过Node_exporter来实现基础的系统监控,并通过Prometheus来查看当前系统可用的磁盘大小
-
服务端安装
# 安装Prometheus [root@docker2 ~]# tar xf prometheus-2.27.1.linux-amd64.tar.gz [root@docker2 ~]# mv prometheus-2.27.1.linux-amd64 /usr/local/prometheus [root@docker2 ~]# ls /usr/local/prometheus/ console_libraries consoles LICENSE NOTICE prometheus prometheus.yml promtool # 创建数据目录 [root@docker2 ~]# mkdir -p /data/prometheus # 给定启动脚本 [root@docker2 ~]# cat > /usr/lib/systemd/system/prometheus.service << EOF [Unit] Description=Prometheus Server After=network.target [Service] ExecStart=/usr/local/prometheus/prometheus --config.file=/usr/local/prometheus/prometheus.yml --web.read-timeout=5m --web.max-connections=10 --storage.tsdb.retention=15d --storage.tsdb.path=/data/prometheus --query.max-concurrency=20 --query.timeout=2m ExecStop=/usr/bin/pkill prometheus Restart=on-failure User=root [Install] WantedBy=multi-user.target EOF # 启动服务并查看端口 [root@docker2 ~]# systemctl start prometheus.service^C [root@docker2 ~]# ss -tnlp | grep 9090 LISTEN 0 32768 [::]:9090 [::]:* users:(("prometheus",pid=1951,fd=8))
-
wget https://github.com/prometheus/prometheus/releases/download/v2.27.1/prometheus-2.27.1.linux-amd64.tar.gz wget https://github.com/prometheus/alertmanager/releases/download/v0.22.2/alertmanager-0.22.2.linux-amd64.tar.gz wget https://storage.googleapis.com/golang/go1.15.11.linux-amd64.tar.gz wget https://dl.grafana.com/oss/release/grafana-7.5.9.linux-amd64.tar.gz
-
客户端安装
[root@docker2 ~]# tar xf node_exporter-1.1.2.linux-amd64.tar.gz [root@docker2 ~]# mv node_exporter-1.1.2.linux-amd64 /usr/local/node_exporter [root@docker2 ~]# cat > /usr/lib/systemd/system/node-exporter.service << EOF [Unit] Description=Node Exporter After=network.target [Service] ExecStart=/usr/local/node_exporter/node_exporter \ --collector.systemd \ --collector.systemd.unit-include="(activemq|solr|smail|mailcenter|sendqueue|convert|cal|smailserver).service" ExecReload=/bin/kill -HUP \$MAINPID TimeoutStopSec=20s Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target EOF # 启动默认端口是9100, --web.listen-address和--web.telemetry-path参数来设置端口和路径 node_exporter --web.listen-address=":9600" --web.telemetry-path="/node_metrics" # 说明: 将node_exporter绑定端口9600并在路径/node_metrics暴漏指标
-
服务端配置
[root@docker2 ~]# grep -Ev "^#|^$" /usr/local/prometheus/prometheus.yml global: scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute. evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute. # scrape_timeout is set to the global default (10s). alerting: alertmanagers: - static_configs: - targets: # - alertmanager:9093 rule_files: # - "first_rules.yml" # - "second_rules.yml" 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:9090'] - job_name: 'node_exporter' # 添加要查看的节点 exporter static_configs: - targets: ['192.168.0.236:9100'] # 检验配置文件是否正确 prometheus]# ./promtool check config prometheus.yml Checking prometheus.yml SUCCESS: 0 rule files found [root@docker2 ~]# systemctl restaus prometheus
-
配置段详解
-
global: 包含了控制prometheus服务器行为的全局配置
- scrape_interval: 用来指定应用程序或服务抓取数据的时间间隔(示例为15秒), 为了确保所有的时间序列具有相同的颗粒度,并且可以组合在一起,最好将抓取间隔为全局参数以保持颗粒度一致
- evaluation_interval: 用来指定prometheus评估规则的频率,目前主要有两种:记录规则和警报规则
- 记录规则: 允许预先计算使用频繁且开销大的表达式,并将结果保存为一个新的时间序列数据
- 警报规则:允许定义警报条件
-
alerting: 用来设置prometheus的警报,警报是由alertmanager的独立工具进行管理
-
rule_files: 用来指定包含记录规则或警报规则的文件列表
-
**scrape_configs:**用来指定prometheus抓取的所有目标
- job_name: 'prometheus' # 实例名,对应 instance static_configs: - targets: ['localhost:9090'] # 要抓取的端点 endpoint
-