为什么说Prometheus是足以取代Zabbix的监控神器?

陈晓宇 2019-09-23 10:11:55
本文根据dbaplus社群第198期线上分享整理而成,文末还有好书推荐哦~

 

一、简介

 

Kubernetes自从2012年开源以来便以不可阻挡之势成为容器领域调度和编排的领头羊,Kubernetes是Google Borg系统的开源实现,于此对应Prometheus则是Google BorgMon的开源实现。Prometheus是由SoundCloud开发的开源监控报警系统和时序列数据库。从字面上理解,Prometheus由两个部分组成,一个是监控报警系统,另一个是自带的时序数据库(TSDB)。

 

2016年,由Google发起的Linux基金会旗下的原生云基金会(Cloud Native Computing Foundation)将Prometheus纳入其第二大开源项目。Prometheus在开源社区也十分活跃,在GitHub上拥有两万多Star,并且系统每隔一两周就会有一个小版本的更新。

 

二、各种监控工具对比

 

其实,在Prometheus之前市面已经出现了很多的监控系统,如Zabbix、Open-Falcon、Nagios等。那么Prometheus和这些监控系统有啥异同呢?我们先简单回顾一下这些监控系统。

 

1、Zabbix
 

 

Zabbix是由Alexei Vladishev开源的分布式监控系统,支持多种采集方式和采集客户端,同时支持SNMP、IPMI、JMX、Telnet、SSH等多种协议,它将采集到的数据存放到数据库中,然后对其进行分析整理,如果符合告警规则,则触发相应的告警。

 

 

Zabbix核心组件主要是Agent和Server,其中Agent主要负责采集数据并通过主动或者被动的方式采集数据发送到Server/Proxy,除此之外,为了扩展监控项,Agent还支持执行自定义脚本。Server主要负责接收Agent发送的监控信息,并进行汇总存储,触发告警等。

 

Zabbix Server将收集的监控数据存储到Zabbix  Database中。Zabbix   Database支持常用的关系型数据库,如果MySQL、PostgreSQL、Oracle等,默认是MySQL,并提供Zabbix Web页面(PHP编写)数据查询。

 

Zabbix由于使用了关系型数据存储时序数据,所以在监控大规模集群时常常在数据存储方面捉襟见肘。所以从Zabbix 4.2版本后开始支持TimescaleDB时序数据库,不过目前成熟度还不高。

 

2、Open-Falcon
 

 

 

Open-Falcon是小米开源的企业级监控工具,用Go语言开发而成,包括小米、滴滴、美团等在内的互联网公司都在使用它,是一款灵活、可扩展并且高性能的监控方案,主要组件包括了:

 

1)Falcon-agent是用Go语言开发的Daemon程序,运行在每台Linux服务器上,用于采集主机上的各种指标数据,主要包括CPU、内存、磁盘、文件系统、内核参数、Socket连接等,目前已经支持200多项监控指标。并且,Agent支持用户自定义的监控脚本。

 

2)Hearthbeat server简称HBS心跳服务,每个Agent都会周期性地通过RPC方式将自己的状态上报给HBS,主要包括主机名、主机IP、Agent版本和插件版本,Agent还会从HBS获取自己需要执行的采集任务和自定义插件。

 

3)Transfer负责接收Agent发送的监控数据,并对数据进行整理,在过滤后通过一致性Hash算法发送到Judge或者Graph。

 

4)Graph是基于RRD的数据上报、归档、存储组件。Graph在收到数据以后,会以rrdtool的数据归档方式来存储,同时提供RPC方式的监控查询接口。

 

5)Judge告警模块,Transfer转发到Judge的数据会触发用户设定的告警规则,如果满足,则会触发邮件、微信或者回调接口。这里为了避免重复告警引入了Redis暂存告警,从而完成告警的合并和抑制。

 

6)Dashboard是面向用户的监控数据查询和告警配置界面。

 

3、Nagios
 

 

 

Nagios原名为NetSaint,由Ethan Galstad开发并维护。Nagios是一个老牌监控工具,由C语言编写而成,主要针对主机监控(CPU、内存、磁盘等)和网络监控(SMTP、POP3、HTTP和NNTP等),当然也支持用户自定义的监控脚本。

 

它还支持一种更加通用和安全的采集方式NREP(Nagios Remote Plugin Executor),它首先在远端启动一个NREP守护进程,用于在远端主机上面运行检测命令,在Nagios服务端用check nrep的plugin插件通过SSL对接到NREP守护进程执行相应的监控行为。相比SSH远程执行命令的方式,这种方式更加安全。

 

4、Prometheus
 

 

 

Prometheus是由SoundCloud开发的开源监控报警系统和时序列数据库。Prometheus的基本原理是通过HTTP周期性抓取被监控组件的状态,任意组件只要提供对应的HTTP接口并且符合Prometheus定义的数据格式,就可以接入Prometheus监控。

 

Prometheus Server负责定时在目标上抓取metrics(指标)数据并保存到本地存储里面。Prometheus采用了一种Pull(拉)的方式获取数据,不仅降低客户端的复杂度,客户端只需要采集数据,无需了解服务端情况,而且服务端可以更加方便的水平扩展。

 

如果监控数据达到告警阈值Prometheus Server会通过HTTP将告警发送到告警模块alertmanger,通过告警的抑制后触发邮件或者webhook。Prometheus支持PromQL提供多维度数据模型和灵活的查询,通过监控指标关联多个tag的方式,将监控数据进行任意维度的组合以及聚合。

 

5、综合对比
 

 

 

1)综合对比如上面的表格,从开发语言上看,为了应对高并发和快速迭代的需求,监控系统的开发语言已经慢慢从C语言转移到Go。不得不说,Go凭借简洁的语法和优雅的并发,在Java占据业务开发,C占领底层开发的情况下,准确定位中间件开发需求,在当前开源中间件产品中被广泛应用。

 

2)从系统成熟度上看,Zabbix和Nagios都是老牌的监控系统:Nagios是在1999年出现的,Zabbix是在1998年出现的,系统功能比较稳定,成熟度较高。而Prometheus和Open-Falcon都是最近几年才诞生的,虽然功能还在不断迭代更新,但站在巨人的肩膀之上,在架构设计上借鉴了很多老牌监控系统的经验;

 

3)从系统扩展性方面看,Zabbix和Open-Falcon都可以自定义各种监控脚本,并且Zabbix不仅可以做到主动推送,还可以做到被动拉取,Prometheus则定义了一套监控数据规范,并通过各种exporter扩展系统采集能力。

 

4)从数据存储方面来看,Zabbix采用关系数据库保存,这极大限制了Zabbix采集的性能,Nagios和Open-Falcon都采用RDD数据存储,Open-Falcon还加入了一致性hash算法分片数据,并且可以对接到OpenTSDB,而Prometheus自研一套高性能的时序数据库,在V3版本可以达到每秒千万级别的数据存储,通过对接第三方时序数据库扩展历史数据的存储;

 

5)从配置复杂度上看,Prometheus只有一个核心server组件,一条命令便可以启动,相比而言,其他系统配置相对麻烦,尤其是Open-Falcon

 

6)从社区活跃度上看,目前Zabbix和Nagios的社区活跃度比较低,尤其是Nagios,Open-Falcon虽然也比较活跃,但基本都是国内的公司参与,Prometheus在这方面占据绝对优势,社区活跃度最高,并且受到CNCF的支持,后期的发展值得期待;

 

7)从容器支持角度看,由于Zabbix和Nagios出现得比较早,当时容器还没有诞生,自然对容器的支持也比较差。Open-Falcon虽然提供了容器的监控,但支持力度有限。Prometheus的动态发现机制,不仅可以支持swarm原生集群,还支持Kubernetes容器集群的监控,是目前容器监控最好解决方案。Zabbix在传统监控系统中,尤其是在服务器相关监控方面,占据绝对优势。而Nagios则在网络监控方面有广泛应用,伴随着容器的发展,Prometheus开始成为主导及容器监控方面的标配,并且在未来可见的时间内被广泛应用。

 

总体来说,对比各种监控系统的优劣,Prometheus可以说是目前监控领域最锋利的“瑞士军刀”了。

 

三、Prometheus功能介绍

 

下图是Prometheus整体架构图。左侧是各种数据源主要是各种符合Prometheus数据格式的exporter,除此之外为了支持推送数据的Agent,可以通过Pushgateway组件,将Push转化为Pull。Prometheus甚至可以从其它的Prometheus获取数据,后面介绍联邦的时候详细介绍。

 

 

图片的上侧是服务发现,Prometheus支持监控对象的自动发现机制,从而可以动态获取监控对象,虽然Zabbix和Open-Falcon也支持动态发现机制,但Prometheus支持最完善。

 

图片中间是核心,通过Retrieval模块定时拉取数据,通过Storage模块保存数据。PromQL是Prometheus提供的查询语法,PromQL通过解析语法树,查询Storage模块获取监控数据。图片右侧是告警和页面展现,页面查看除了Prometheus自带的webui,还可以通过grafana等组件查询Prometheus监控数据。

 

Prometheus指标格式分为两个部分:一是指标名称,另一个是指标标签。格式如下:

 

 

<metric name>{<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指标类型有四种:

 

1)Counter(计数器):计数统计,累计多长或者累计多少次等。它的特点是只增不减,譬如HTTP访问总量;

 

2)Gauge(仪表盘):数据是一个瞬时值,如果当前内存用量,它随着时间变化忽高忽低。

 

 

如果需要了解某个时间段内请求的响应时间,通常做法是使用平均响应时间,但这样做无法体现数据的长尾效应。例如,一个HTTP服务器的正常响应时间是30ms,但有很少几次请求耗时3s,通过平均响应时间很难甄别长尾效应,所以Prometheus引入了Histogram和Summary。

 

3)Histogram(直方图):服务端分位,不同区间内样本的个数,譬如班级成绩,低于60分的9个,低于70分的10个,低于80分的50个。

 

4)Summary(摘要):客户端分位,直接在客户端通过分位情况,还是用班级成绩举例:0.8分位的是,80分,0.9分为85分,0.99分为的是98分。

 

 

Prometheus通过HTTP接口的方式从各种客户端获取数据,这些客户端必须符合Prometheus监控数据格式,通常由两种方式,一直是侵入式埋点监控,通过在客户端集成如果Kubernetes API直接通过引入Prometheus go client,提供/metrics接口查询kubernetes API各种指标。

 

另一种是通过exporter方式,在外部将原来各种中间件的监控支持转化为Prometheus的监控数据格式,如redis exporter将reids指标转化为Prometheus能够识别的HTTP请求。

 

Prometheus并没有采用json的数据格式,而是采用 text/plain 纯文本的方式 ,这是它的特殊之处。

 

HTTP返回Header和Body如上图所示,指标前面两行#是注释,标识指标的含义和类型。指标和指标的值通过空格分割,开发者通常不需要自己拼接这种个数的数据, Prometheus提供了各种语言的SDK支持。

 

 

Prometheus为了支持各种中间件以及第三方的监控提供了exporter,大家可以把它理解成监控适配器,将不同指标类型和格式的数据统一转化为Prometheus能够识别的指标类型。

 

譬如Node exporter主要通过读取linux的/proc以及/sys目录下的系统文件获取操作系统运行状态,reids exporter通过reids命令行获取指标,mysql exporter通过读取数据库监控表获取mysql的性能数据。他们将这些异构的数据转化为标准的Prometheus格式,并提供HTTP查询接口。

 

 

Prometheus提供了两种数据持久化方式:一种是本地存储,通过Prometheus自带的tsdb(时序数据库),将数据保存到本地磁盘,为了性能考虑,建议使用SSD。但本地存储的容量毕竟有限,建议不要保存超过一个月的数据。Prometheus本地存储经过多年改进,自Prometheus 2.0后提供的V3版本tsdb性能已经非常高,可以支持单机每秒1000w个指标的收集。

 

另一种是远端存储,适用于大量历史监控数据的存储和查询。通过中间层的适配器的转化,Prometheus将数据保存到远端存储。适配器实现Prometheus存储的remote write和remote read接口并把数据转化为远端存储支持的数据格式。目前,远端存储主要包括OpenTSDB、InfluxDB、Elasticsearch、M3db、Kafka等,其中M3db是目前非常受欢迎的后端存储。

 

 

和关系型数据库的SQL类似,Prometheus也内置了数据查询语言PromQL,它提供对时间序列数据丰富的查询,聚合以及逻辑运算的能力。一条PromQL主要包括了指标名称、过滤器以及函数和参数。指标可以进行数据运算,包括+ (加法)、- (减法)、* (乘法)、/ (除法)、% (求余)、^ (幂运算),聚合函数包括了:sum (求和)、min (最小值)、max (最大值)、avg (平均值)、stddev (标准差)、count (计数)、topk (前n条)、quantile (分布统计)等。查询数据通过HTTP GET请求发送PromQL查询语句。形式如:

 

 

curl 'http://Prometheus:9090/api/v1/query?query=up&time=2015-07-01T20:10:51.781Z'

 

其中query参数就是一条PromQL表达式。除此之外还支持范围查询query_range,需要额外添加start(起始时间)、end(结束时间)、step(查询步长)这三个参数。无论是Prometheus自带的webui还可以通过grafana,他们本质上都是通过HTTP发送PromQL的方式查询Prometheus数据。整个解析流程如下所示:

 

 

当Prometheus接收请求后,通过PromQL引擎解析PromQL,确定查询时间序列和查询时间范围,通过tsdb接口获取对应数据块,最后根据聚合函数处理监控数据并返回。

 

 

Prometheus告警配置也是通过yaml文件配置,核心是上面的expr参数(告警规则)和查询一样也是一个PromQL表达式。for代表持续时间,如果在for时间内持续触发,Prometheus才发出告警至alertmanger。

 

告警组件alertmanger地址是在Prometheus的配置文件中指定,告警经过alertmanger去重、抑制等操作,最后执行告警动作,目前支持邮件、slack、微信和webhook,如果是对接钉钉,便可以通过webhook方式触发钉钉的客户端发送告警。

 

 

Prometheus配置监控对象有两种方式,一种是通过静态文件配置,另一种是动态发现机制,自动注册监控对象。

 

Prometheus动态发现目前已经支持Kubernetes、etcd、Consul等多种服务发现机制,动态发现机制可以减少运维人员手动配置,在容器运行环境中尤为重要,容器集群通常在几千甚至几万的规模,如果每个容器都需要单独配置监控项不仅需要大量工作量,而且容器经常变动,后续维护更是异常麻烦。针对Kubernetes环境的动态发现,Prometheus通过watch kubernetes api动态获取当前集群所有服务和容器情况,从而动态调整监控对象。

 

 

为了扩展单个Prometheus的采集能力和存储能力,Prometheus引入了“联邦”的概念。

 

多个Prometheus节点组成两层联邦结构,如图所示,上面一层是联邦节点,负责定时从下面的Prometheus节点获取数据并汇总,部署多个联邦节点是为了实现高可用。下层的Prometheus节点又分别负责不同区域的数据采集,在多机房的事件部署中,下层的每个Prometheus节点可以被部署到单独的一个机房,充当代理。

 

四、Prometheus落地实践

 

首先先简单介绍一下宜信容器这个产品,它是宜信内部基于Kubernetes搭建的容器管理平台,用户可以通过平台一键部署自己的服务。平台主要功能包括了服务管理(灰度发布、自动伸缩、多集群部署等)、镜像管理、监控告警、CICD、Nginx管理、Ceph存储等多个功能。

 

 

其中监控和告警和自动伸缩都是基于Prometheus构建。

 

 

Prometheus采集的数据包括了主机性能监控、容器性能监控、nginx访问流量、Kubernetes状态以及平台各个自研组件的性能指标。

 

Prometheus一方面为页面提供性能指标查询,如果nginx qps、容器cpu利用率,另一方便提供基于这些指标的性能告警,告警发送至alertmanger中,并通过alertmanger的webhook触发后续的告警处理。

 

 

为了支持容器的多指标、多集群自动伸缩,平台开发一套自动伸缩模块,通过定时获取Prometheus监控指标,通过上面的公式(指标和除以目标值)计算出目标的容器副本数,最后通过调用Kubernetes接口扩展容器副本。

 

最后我想表达,Prometheus也并非银弹。

 

首先,Prometheus只针对性能和可用性监控,并不具备日志监控等功能,并不能通过Prometheus解决所有监控问题。

 

其次,Prometheus认为只有最近的监控数据才有查询的需要,所有Prometheus本地存储的设计初衷只是保持短期(一个月)的数据,并非针对大量的历史数据的存储。如果需要报表之类的历史数据,则建议使用Prometheus的远端存储如OpenTSDB、m3db等。

 

Prometheus还有一个小瑕疵是没有定义单位,这里需要使用者自己去区分或者事先定义好所有监控数据单位,避免数据缺少单位问题。

 

 

>>>>

Q & A

 

Q1:Prometheus能替代Zabbix吗?

A:在我们公司实际的生产环境中Prometheus完全可以替代Zabbix。并且由于我个人主要负责容器云的建设,对Prometheus更加青睐。

 

Q2:如何对Prometheus进行权限限制?类似于Zabbix的用户密码校验。

A:其实Prometheus本身没有任何的权限限制,因为它只作为一套监控系统,它认为这种权限的管理应该属于上面的管理权限系统去维护,而不应该在它这样一套监控系统里做,所以Prometheus本身在设计上就没有做任何的权限管理。

 

在我们宜信内部使用容器云的时候,其实针对Prometheus数据查询时,因为我们在容器云平台本身有一套权限管理,所以每个用户只能看到自己的容器,当然他只能看到自己容器的监控数据。

 

Q3:Prometheus可以监控web地址吗?类似于Zabbix的web场景。

A:Prometheus结合blockbox可以去监控一些web站点是不是健康,它会定时去调用一些你们提供的web接口,然后通过分析接口返回码或者是返回体,判断web服务是否健康,可以作为站点监控。除此之外还支持TCP、DNS、ICMP以及HTTPS。

 

Q4:Prometheus和Ansible有相同作用么?

A:我理解的Ansible其实大多数来说还是一种自动化运维工具,它虽然有一些简单监控,但是核心并不在监控上面,而是自动化部署和运维上的一些能力,而Prometheus本身只是一个单纯的监控和告警的组件。

 

Q5:请老师对比下InfluxDB和Prometheus,个人觉得InfluxDB易用性更好。

A:InfluxDB本身没有任何监控数据的能力,InfluxDB的商业版本是集群的,可以存储大量的数据,但是开源版本是单机的,不建议使用。Prometheus不但具有数据存储能力,还在数据指标采集能力,而单纯的InfluxDB只有数据存储能力。

 

Q6:宜信内部只用Prometheus做监控?还用其他产品配合吗?

A:在宜信公司内部,之前使用的是Zabbix监控,目前正在从Zabbix监控切换到Prometheus监控里。

 

Q7:哪种监控工具更适合做业务指标监控?

A:我个人接触过的业务指标监控主要是通过Graphite、Prometheus以及宜信开源的UAV监控,通常的业务指标监控都是通过埋点完成,大同小异。

 

Q8:Prometheus监控Oracle、MySQL数据库方便吗?

A:由于现在各种Prometheus export非常丰富,针对这些中间件,如Oracle、MySQL这种监控是非常方便的。目前也支持得比较好,在我们自己的环境里面,我们通过Kafka的export、MySQL的export、Redis的export分别去监控我们自己的组件状态,如果你有一些自己定制的监控指标,也可以去定制一些export,这些东西都比较简单,并不是很困难。

 

Q9:Prometheus用什么存储比较好?本地存储容量有限。

A:在我们实际生产环境中本地存储只保留一个月数据,历史数据都放到M3db中保存。

 

Q10:我目前监控一种类型的对象,就需要一个exporter,对象越多exporter的量也不断增长,怎么解决?

A:大部分的监控对象都需要特定类型exporter,因为每种类型的监控指标的数据格式不一样,都要特定的exporter去解析这种指标,并且转换为Prometheus识别的指标类型。至于说exporter的量非常多,exporter本身是很轻量级的,其实虽然多,但是在我们自己部署的环境里面,有的时候就和我们的应用捆绑到一个Pod去部署,其实非常方便维护,本身也不会有什么负载压力,exporter本身很稳定,维护起来也非常简单。

 

Q11:非容器化部署的中间件也能监控吗?

A:其实Prometheus采集数据的时候,只适合采集数据的监控格式是否满足它的需求,它本身并不关心被监控对象是不是在容器里面,没有任何关系。只要对外暴露的监控数据格式符合Prometheus的要求就可以。

 

Q12:rancher如何配合Prometheus使用?

A:如果你使用rancher这种第三方的容器平台,其实Prometheus本身和Kubernetes结合得非常紧密,你直接可以在rancher里部署一个Prometheus。它本身只针对于Kubernetes这种监控,因为rancher的底层也是Kubernetes,所以在ranche里部署Prometheus去监控指标,这个是没有问题的。

 

Q13:Prometheus能把时序数据实时发动到Kafka吗?

A:可以的,目前社区已经有一个Kafka的exporter,可以把监控数据写到Kafka里。

 

Q14:Prometheus除了联邦集群的方式,是否存在心跳或者类似集群化的部署?

A:Improbable开源的Thanos提供了Prometheus集群化能力,感兴趣的朋友可以深入了解一下。

 

Q15:Prometheus配置网络设备时,有什么简易方式吗?设备类型跟OID有一定差异的情况下,有什么简易方式?

A:Prometheus通过SNMP exporter监控网络设备时,OID也需要单独配置,目前没有啥好办法。

 

Q16:如何更好地阅读Prometheus的源码?Prometheus的源码质量如何?

A:Prometheus代码包结构清晰,对于学习Go语言的朋友可以深度走读一遍。建议首先看数据采集和PromQL解析,最后看TSDB。

 

Q17:Prometheus未来会向哪个方向发展?

A:Prometheus目前正在慢慢成为基于HTTP监控的规范,目前在容器领域和kubernetes一起,已经确定了领导地位,越来越多的中间件也开始原生支持Prometheus监控。Prometheus 3.x即将发布,主要增强集群能力、数据存储能力以及安全性。

 

>>>>

直播回放

 

https://m.qlchat.com/topic/details?topicId=2000005988804996

新书推荐



如果想更全面更深入地了解Prometheus,推荐大家看看陈晓宇老师参与撰写的新书《深入浅出Prometheus》。

 

 


最新评论
访客 2023年08月20日

230721

访客 2023年08月16日

1、导入Mongo Monitor监控工具表结构(mongo_monitor…

访客 2023年08月04日

上面提到: 在问题描述的架构图中我们可以看到,Click…

访客 2023年07月19日

PMM不香吗?

访客 2023年06月20日

如今看都很棒

活动预告