监控告警-Prometheus
第一章:概述
本章将介绍监控告警的一些基本概念。
1.1 什么是监控告警?
-
监控是什么?
说白了就是用一种形式去盯着、观察服务器,把服务器的各种行为表现都显示出来,用以发现问题和不足。
-
告警是什么?
监控和告警这两个词需要分开来理解,监控是监控,告警是告警。监控是把行为表现展现出来,用来观察的。告警则是当监控获取的数据发生异常并且达到了某个临界点的时候,采用各种途径来通知用户、管理员、运维人员甚至是老板。
告警系统中最重要的一个概念之一就是对告警阈值的理解。阈值(
Trigger Value
)是监控系统中对数据达到某一个临界值的定义。
1.2 监控都有哪些组成部分和流程?
监控本身看的是数据,数据从哪里来?
数据不是凭空从天上掉下来的,也不是研发人员主动给的,只能是从运维数据采集来。
1.3 监控设计
-
评估系统的业务流程、业务种类、架构体系
各个企业的产品不同,业务方向不同,程序代码不同,系统架构更不同
对于各个地方的细节都需要有一定程度的认知,才可以开起设计的源头
-
分类出所需的监控项种类
一般可以分为:业务级别监控/系统级别监控/网络监控/程序代码监控/日志监控/用户行为分析监控/其他种类监控
- 业务监控: 可以包含用户访问
QPS
,DAU
日活,访问状态,业务接口(登录、注册、上传、聊天、留言、短信、搜索等),产品转化率,充值额度,用户投诉等等这些很宏观的概念 - 系统监控:主要是跟操作系统相关的基本监控项,CUP/内存/硬盘/IO/TCP连接/流量等等
- 网络监控:对网络状态的监控(交换机、路由器、防火墙、
vpn
等,应用更多的是直接对主机的网络监控),互联网公司必不可少,但很多时候又被忽略,如:内网之间(物理内网、逻辑内网、云平台可用区等)、外网、丢包率、延迟等 - 日志监控:监控中的重头戏,往往单独设计和搭建,全部种类的日志都需要有采集(
syslog
,soft
,网络设备,用户行为) - 程序监控:一般需要和开发人员配合,程序中嵌入各种接口,直接获取数据或者特质的日志格式
- 业务监控: 可以包含用户访问
第二章:Prometheus简介
本章将介绍 Prometheus
的特点、架构以及与一些流行监控工具的比较。
2.1 什么是Prometheus?
Prometheus is an open-source systems monitoring and alerting toolkit originally built at
SoundCloud
. Since its inception in 2012, many companies and organizations have adopted Prometheus, and the project has a very active developer and user community. It is now a standalone open source project and maintained independently of any company. To emphasize this, and to clarify the project's governance structure, Prometheus joined the Cloud Native Computing Foundation in 2016 as the second hosted project, afterKubernetes
.
Prometheus
受启发于Google
的Brogmon
监控系统(相似的Kubernetes
是从Google
的Brog
系统演变而来),从2012年开始由前Google
工程师在Soundcloud
以开源软件的形式进行研发,并且于2015年早期对外发布早期版本。2016年5月继Kubernetes
之后成为第二个正式加入CNCF
基金会的项目,同年6月正式发布1.0版本。2017年底发布了基于全新存储层的2.0版本,能更好地与容器平台、云平台配合,2018年8月Prometheus
正式从CNCF
毕业,预示着Prometheus
将走入企业,支撑着大大小小的公司,帮助他们完成新一代监控系统的过渡。
2.2 Prometheus的特点
- 多维数据模型(时序由
metric
名字和k/v
的labels
构成)。 - 灵活的查询语句(
PromQL
)。 - 无依赖分布式存储,支持
local
和remote
不同模型,单个服务器节点是自主的。 - 通过基于
http
协议的pull
方式采集时序数据,简单易懂。 - 可以通过中间网关进行时序数据推送。
- 可以通过服务发现或静态配置的方式来发现目标服务对象。
- 支持多种统计数据模型,图形化友好。
2.3 Prometheus组织架构
2.3.1 基本原理
Prometheus
的基本原理是通过HTTP
协议周期性抓取被监控组件的状态,任意组件只要提供对应的HTTP接口就可以接入监控。不需要任何SDK
或者其他的集成过程。这样做非常适合做虚拟化环境监控系统,比如VM
、Docker
、Kubernetes
等。输出被监控组件信息的HTTP
接口被叫做exporter
。目前互联网公司常用的组件大部分都有exporter
可以直接使用,比如Varnish、Haproxy、Nginx、MySQL、Linux
系统信息(包括磁盘、内存、CPU、网络等等)。
2.3.2 核心组件
2.3.2.1 Prometheus server
Prometheus Server
是Prometheus
组件中的核心部分,负责实现对监控数据的获取,存储以及查询。Prometheus Server
可以通过静态配置管理监控目标,也可以配合使用Service Discovery
的方式动态管理监控目标,并从这些监控目标中获取数据。其次Prometheus Server
需要对采集到的监控数据进行存储,Prometheus Server
本身就是一个时序数据库,将采集到的监控数据按照时间序列的方式存储在本地磁盘当中。最后Prometheus Server
对外提供了自定义的PromQL
语言,实现对数据的查询以及分析。Prometheus Server
内置的Express Browser UI
,通过这个UI可以直接通过PromQL
实现数据的查询以及可视化。Prometheus Server
的联邦集群能力可以使其从其他的Prometheus Server
实例中获取数据,因此在大规模监控的情况下,可以通过联邦集群以及功能分区的方式对Prometheus Server
进行扩展。
2.3.2.2 Exporters
Exporter
将监控数据采集的端点通过HTTP
服务的形式暴露给Prometheus Server
,Prometheus Server
通过访问该Exporter
提供的Endpoint
端点,即可获取到需要采集的监控数据。
一般来说可以将Exporter
分为2类:
直接采集:这一类
Exporter
直接内置了对Prometheus
监控的支持,比如cAdvisor
,Kubernetes
,Etcd
,Gokit
等,都直接内置了用于向Prometheus
暴露监控数据的端点。间接采集:间接采集,原有监控目标并不直接支持
Prometheus
,因此我们需要通过Prometheus提供的ClientLibrary
编写该监控目标的监控采集程序。例如:Mysql Exporter
,JMX Exporter
,Consul Exporter
等。
2.3.2.3 AlertManager
在Prometheus Server
中支持基于PromQL
创建告警规则,如果满足PromQL
定义的规则,则会产生一条告警,而告警的后续处理流程则由AlertManager
进行管理。在AlertManager
中我们可以与邮件,Slack
等等内置的通知方式进行集成,也可以通过Webhook
自定义告警处理方式。
2.3.2.4 PushGateway
由于Prometheus
数据采集基于Pull
模型进行设计,因此在网络环境的配置上必须要让Prometheus Server
能够直接与Exporter
进行通信。 当这种网络需求无法直接满足时,就可以利用PushGateway
来进行中转。可以通过PushGateway
将内部网络的监控数据主动Push
到Gateway
当中。而Prometheus Server
则可以采用同样Pull
的方式从PushGateway
中获取到监控数据。
Pushgateway
是 Prometheus
生态中一个重要工具,使用它的原因主要是:
-
Prometheus
采用pull
模式,可能由于不在一个子网或者防火墙原因,导致Prometheus
无法直接拉取各个target
数据。 - 在监控业务数据的时候,需要将不同数据汇总, 由
Prometheus
统一收集。
由于以上原因,不得不使用 pushgateway
,但在使用之前,有必要了解一下它的一些弊端:
- 将多个节点数据汇总到
pushgateway
, 如果pushgateway
挂了,受影响比多个target
大。 -
Prometheus
拉取状态up
只针对pushgateway
, 无法做到对每个节点有效。 -
Pushgateway
可以持久化推送给它的所有监控数据。
因此,即使你的监控已经下线,prometheus
还会拉取到旧的监控数据,需要手动清理 pushgateway
不要的数据。
2.3.2.5 Service Discovery
服务发现在Prometheus
中是特别重要的一个部分,基于Pull
模型的抓取方式,需要在Prometheus
中配置大量的抓取节点信息才可以进行数据收集。有了服务发现后,用户通过服务发现和注册的工具对成百上千的节点进行服务注册,并最终将注册中心的地址配置在Prometheus
的配置文件中,大大简化了配置文件的复杂程度, 也可以更好的管理各种服务。
在众多云平台中(
AWS,OpenStack
),Prometheus
可以 通过平台自身的API
直接自动发现运行于平台上的各种服务,并抓取他们的信息Kubernetes
掌握并管理着所有的容器以及服务信息,那此时Prometheus
只需要与Kubernetes
打交道就可以找到所有需要监控的容器以及服务对象Consul
(官方推荐)等服务发现注册软件通过
DNS
进行服务发现通过静态配置文件(在服务节点规模不大的情况下)
2.3.2.6 Storage
Prometheus
提供了两种数据持久化方式:一种是本地存储,通过Prometheus
自带的TSDB
(时序数据库),将数据保存到本地磁盘,为了性能考虑,建议使用SSD
。但本地存储的容量毕竟有限,建议不要保存超过一个月的数据。Prometheus
本地存储经过多年改进,自Prometheus 2.0
后提供的V3
版本TSDB
性能已经非常高,可以支持单机每秒1000w
个指标的收集。
Prometheus
本地数据存储能力一直为大家诟病,但Prometheus
本地存储设计的初衷就是为了监控数据的查询,Facebook
发现85%的查询是针对26小时内的数据。所以Prometheus
本地时序数据库的设计更多考虑的是高性能而非分布式大容量。
另一种是远端存储,适用于大量历史监控数据的存储和查询。通过中间层的适配器的转化,Prometheus
将数据保存到远端存储。适配器实现Prometheus
存储的remote write
和remote read
接口,并把数据转化为远端存储支持的数据格式。目前,远端存储主要包括OpenTSDB
、InfluxDB
、Elasticsearch
、M3DB
等,其中M3DB
是目前非常受欢迎的后端存储。
运维方面:
Prometheus has several flags that allow configuring the local storage. The most important ones are:
-
--storage.tsdb.path
: This determines where Prometheus writes its database. Defaults todata/
. -
--storage.tsdb.retention.time
: This determines when to remove old data. Defaults to15d
. Overridesstorage.tsdb.retention
if this flag is set to anything other than default. -
--storage.tsdb.retention.size
: [EXPERIMENTAL] This determines the maximum number of bytes that storage blocks can use (note that this does not include the WAL size, which can be substantial). The oldest data will be removed first. Defaults to0
or disabled. This flag is experimental and can be changed in future releases. Units supported: KB, MB, GB, PB. Ex: "512MB" -
--storage.tsdb.retention
: This flag has been deprecated in favour ofstorage.tsdb.retention.time
. -
--storage.tsdb.wal-compression
: This flag enables compression of the write-ahead log (WAL). Depending on your data, you can expect the WAL size to be halved with little extra cpu load. Note that if you enable this flag and subsequently downgrade Prometheus to a version below 2.11.0 you will need to delete your WAL as it will be unreadable.
这几个参数是设置本地存储的配置,自行翻译吧。
On average, Prometheus uses only around 1-2 bytes per sample. Thus, to plan the capacity of a Prometheus server, you can use the rough formula:
needed_disk_space = retention_time_seconds * ingested_samples_per_second * bytes_per_sample
计算Prometheus服务器的容量 ,关于采集时间间隔的设置可以参考文章规划Prometheus的存储用量。
To tune the rate of ingested samples per second, you can either reduce the number of time series you scrape (fewer targets or fewer series per target), or you can increase the scrape interval. However, reducing the number of series is likely more effective, due to compression of samples within a series.
If your local storage becomes corrupted for whatever reason, your best bet is to shut down Prometheus and remove the entire storage directory. Non POSIX compliant filesystems are not supported by Prometheus's local storage, corruptions may happen, without possibility to recover. NFS is only potentially POSIX, most implementations are not. You can try removing individual block directories to resolve the problem, this means losing a time window of around two hours worth of data per block directory. Again, Prometheus's local storage is not meant as durable long-term storage.
If both time and size retention policies are specified, whichever policy triggers first will be used at that instant.
Expired block cleanup happens on a background schedule. It may take up to two hours remove expired blocks. Expired blocks must be fully expired before they are cleaned up.
2.3.3 服务过程
Prometheus server
定期从静态配置的targets
或者服务发现的targets
拉取metrics
(指标)数据。Prometheus
采用PULL
的方式进行监控,即服务器可以直接通过目标PULL
数据或者间接地通过中间网关来Push
数据。PushGateway
支持Client
主动推送metrics
到PushGateway
,而Prometheus
只是定时去Gateway上抓取数据。Prometheus
是将采集过来的数据先存放在内存之中的,并通过一定规则进行清理和整理数据,把得到的结果存储到新的时间序列中。当新拉取的数据大于配置内存缓存区的时候,Prometheus
会将数据持久化到磁盘(如果使用remote storage
将持久化到云端)。Prometheus
可以配置rules
,然后定时查询数据,当条件触发的时候,会将alert
推送到配置的Alertmanager
。Alertmanager
收到警告的时候,会根据配置,聚合,去重,降噪,最后发送警告。Prometheus
通过PromQL
和其他API可视化地展示收集的数据。Prometheus
支持很多方式的图表可视化,例如Grafana
、自带的Promdash
以及自身提供的模版引擎等等。Prometheus
还提供HTTP API
的查询方式,自定义所需要的输出。
注意:
Prometheus
的数据是基于时序的float64
的值,如果你的数据值有更多类型,无法满足。Prometheus
不适合做审计计费,因为它的数据是按一定时间采集的,关注的更多是系统的运行瞬时状态以及趋势,即使有少量数据没有采集也能容忍,但是审计计费需要记录每个请求,并且数据长期存储,这个Prometheus
无法满足,可能需要采用专门的审计系统。
2.4 Prometheus的优势
优势和它的特点是分不开的:
-
基于
time series
时间序列模型(时序由metric
名字和k/v
的labels
构成)时间序列(
time series (X,Y)
)是一系列有序的数据,通常是等时间间隔的采样数据。 -
采样数据的查询完全基于数学运算,二不是其他的表达式,并提供专有的查询输入
console
。这个特点很独特,所有查询都基于数学运算公式,如(增量(A)+增量(B))/ 总增量(C) > 固定百分比,则触发告警。
-
采用
http pull/push
两种对应的数据采集传输方式所有的数据采集都基本采用
http
的形式,且分为pull/push
拉和推两种方式去采集程序,对数据操作很方便。 -
开源,且有大量的社区成品插件
很多
prometheus
社区开发的插件已经异常强大和完善,如果对监控要求不是特别高,默认的几个成品插件装上就可以用到底了。监控成型速度快。 -
push
的方法使用非常灵活push
的这种采集方法灵活度超乎想象,几乎任何形式的数据都可以实现。 -
本身自带图像调试
prometheus
本身自带了现成的图形成型界面,虽然不能跟grafana
的效果相比,但是这种自带图形成图可以方便我们进行调试。 -
最精细的数据采样
大多数市面上的开源监控采样也就能精确到半分钟、一分钟的程度,商品化监控产品就更别提了,为了缩小数据存储的成本,有的甚至是5分钟作为采样最小间隔。
prometheus
理论上可以达到每秒采集,而且可以自行定制频率,可以自行衡量采样时间和存储成本的平衡。
prometheus
一些不足的地方:
- 暂不支持集群。
- 如果集群数量过大,本身监控有性能的瓶颈,如果是集群则可以解决这个问题。
- 偶尔发生数据丢失(2.0之前版本偶尔会发生,2.0之后已解决)。
- 学习成本太大,尤其是独有的数学命令行,各种数学模型概念复杂,中文资料极少。
- 对磁盘资源消耗较大,具体看监控的集群量、监控项的多少和保存时间的长短等。
2.5 Prometheus的适用场景
在选择Prometheus
作为监控工具前,要明确它的适用范围,以及不适用的场景。
-
Prometheus
在记录纯数值时间序列方面表现非常好。它既适用于以服务器为中心的监控,也适用于高动态的面向服务架构的监控。
在微服务的监控上,
Prometheus
对多维度数据采集及查询的支持也是特殊的优势。Prometheus
更强调可靠性,即使在故障的情况下也能查看系统的统计信息。权衡利弊,以可能丢失少量数据为代价确保整个系统的可用性。因此,它不适用于对数据准确率要求100%的系统,比如实时计费系统(涉及到钱)。
2.6 Why Prometheus?
Zabbix |
Prometheus |
---|---|
后端用 C 开发,界面用 PHP 开发,定制化难度很高。 |
后端用 golang 开发,前端是 Grafana ,JSON 编辑即可解决。定制化难度较低。 |
集群规模上限为 10000 个节点。 | 支持更大的集群规模,速度也更快。 |
更适合监控物理机环境。 | 更适合云环境的监控,对 OpenStack ,Kubernetes 有更好的集成。 |
监控数据存储在关系型数据库内,如 MySQL ,很难从现有数据中扩展维度。 |
监控数据存储在基于时间序列的数据库内,便于对已有数据进行新的聚合。 |
安装简单,zabbix-server 一个软件包中包括了所有的服务端功能。 |
安装相对复杂,监控、告警和界面都分属于不同的组件。 |
图形化界面比较成熟,界面上基本上能完成全部的配置操作。 | 界面相对较弱,很多配置需要修改配置文件。 |
发展时间更长,对于很多监控场景,都有现成的解决方案。 | 2015 年后开始快速发展,但发展时间较短,成熟度不及 Zabbix 。 |
开发语言 | 成熟度 | 扩展性 | 高性能 | 社区活跃 | 容器支持 | 企业使用 | 部署维护 | |
---|---|---|---|---|---|---|---|---|
Zabbix |
C、PHP
|
高 | 高 | 低 | 中 | 低 | 高 | 中 |
Open-Falcon | Golang |
中 | 中 | 高 | 中 | 中 | 中 | 高 |
Prometheus | Golang |
中 | 高 | 高 | 高 | 高 | 高 | 低 |
Zabbix
是由Alexei Vladishev
开源的分布式监控系统,支持多种采集方式和采集客户端,同时支持SNMP
、IPMI
、JMX
、Telnet
、SSH
等多种协议,它将采集到的数据存放到数据库中,然后对其进行分析整理,如果符合告警规则,则触发相应的告警。
Open-Falcon
是小米开源的企业级监控工具,用Go
语言开发而成,包括小米、滴滴、美团等在内的互联网公司都在使用它,是一款灵活、可扩展并且高性能的监控方案。
从开发语言上看,为了应对高并发和快速迭代的需求,监控系统的开发语言已经慢慢从
C
语言转移到Go
。不得不说,Go
凭借简洁的语法和优雅的并发,在Java
占据业务开发,C
占领底层开发的情况下,准确定位中间件开发需求,在当前开源中间件产品中被广泛应用。从系统成熟度上看,
Zabbix
是老牌的监控系统:Zabbix
是在1998年出现的,系统功能比较稳定,成熟度较高。而Prometheus
和Open-Falcon
都是最近几年才诞生的,虽然功能还在不断迭代更新,但站在巨人的肩膀之上,在架构设计上借鉴了很多老牌监控系统的经验。从系统扩展性方面看,
Zabbix
和Open-Falcon
都可以自定义各种监控脚本,并且Zabbix
不仅可以做到主动推送,还可以做到被动拉取,Prometheus
则定义了一套监控数据规范,并通过各种exporter
扩展系统采集能力。从数据存储方面来看,
Zabbix
采用关系数据库保存,这极大限制了Zabbix
采集的性能,Open-Falcon
采用RDD
数据存储,并且可以对接到OpenTSDB
,而Prometheus
自研一套高性能的时序数据库,在V3版本可以达到每秒千万级别的数据存储,通过对接第三方时序数据库扩展历史数据的存储。从配置和维护的复杂度上看,
Prometheus
只有一个核心server
组件,一条命令便可以启动,相比而言,其他系统配置相对麻烦,尤其是Open-Falcon
。从社区活跃度上看,目前
Zabbix
社区活跃度比较低,Open-Falcon
虽然也比较活跃,但基本都是国内的公司参与,Prometheus
在这方面占据绝对优势,社区活跃度最高,并且受到CNCF
的支持,后期的发展值得期待。从容器支持角度看,由于
Zabbix
出现得比较早,当时容器还没有诞生,自然对容器的支持也比较差。Open-Falcon
虽然提供了容器的监控,但支持力度有限。Prometheus
的动态发现机制,不仅可以支持Swarm
原生集群,还支持Kubernetes
容器集群的监控,是目前容器监控最好解决方案。Zabbix
在传统监控系统中,尤其是在服务器相关监控方面,占据绝对优势。伴随着容器的发展,Prometheus
开始成为主导及容器监控方面的标配,并且在未来可见的时间内被广泛应用。总体来说,对比各种监控系统的优劣,Prometheus
可以说是目前监控领域最锋利的“瑞士军刀”了。
总结:
Prometheus
属于一站式监控告警平台,依赖少,功能齐全。Prometheus
支持对云的或容器的监控,其他系统主要对主机监控。Prometheus
数据查询语句表现力更强大,内置更强大的统计函数。Prometheus
在数据存储扩展性以及持久性上没有InfluxDB
,OpenTSDB
,Sensu
好。