监控一直是IT系统中的核心组成部分,负责问题的发现以及辅助性的定位。无论是传统运维、SRE、DevOps、开发者都需要关注监控系统并参与到监控系统的建设和优化。从最开始大型机的作业系统、Linux基础指标,监控系统就已经开始出现并逐渐演进,现阶段能够搜索到的监控系统不下于上百种,按照不同类别也有非常多的划分方式,例如:
对于建设一套公司内部使用的监控系统平台,相对来说可选的方案还是非常多的,无论是用开源方案自建还是使用商业的SaaS化产品,都有比较多的可选项。但无论是开源方案还是商业的SaaS产品,真正实施起来都需要考虑如何将数据给到监控平台,或者说监控平台如何获取到这些数据。这里就涉及到数据获取方式的选型:Pull(拉)还是Push(推)模式?
基于Pull类型的监控系统顾名思义是由监控系统主动去获取指标,需要被监控的对象能够具备被远端访问的能力;基于Push类型的监控系统不主动获取数据,而是由监控对象主动推送指标。两种方式在非常多的地方都有区别,对于监控系统的建设和选型来说,一定要事先了解这两种方式各自的优劣,选择合适的方案来实施,否则如果盲目实施,后续对监控系统的稳定性和部署运维代价来说将是灾难性的。
下面将从几个方面来展开介绍,为了节约读者时间,这里先用一个表格来做概要性的论述,细节在后面会展开:
一级分类 | 二级分类 | Pull | Push |
---|---|---|---|
原理与部署 | 配置 | 原生中心化配置 | 端上配置,通过配置中心支持中心化 |
原理与部署 | 监控对象发现 | 依赖服务发现机制,例如Zookeeper、Etcd、Consul等注册中心 | 由应用、Agent自主上报,无需服务发现模块 |
原理与部署 | 部署方式 | 1. 应用暴露端口,接入服务发现,原生支持Pull协议;2. 其他系统例如主机、MySQL、NGINX等中间件依赖适配器(也成为Exporter)去抓取指标再提供Pull端口 | 1. Agent统一代理,抓取主机、MySQL等中间件数据推送到监控系统;Agent也可以作为转发器接收应用推送2. 应用主动推送到监控系统 |
扩展性 | 可扩展性 | 依赖Pull端扩展;需要Pull Agent和存储解耦(原生Prometheus不支持);Push Agent按照分片划分 | 简单,本身Agent可横向扩展 |
能力对比 | 监控对象存活性 | 简单 | 无法区分对象未存活的原因 |
能力对比 | 数据齐全度计算 | 1. Pull端和存储耦合部署时较简单2. Pull Agent分布式部署下较困难 较困难 | 较困难 |
能力对比 | 短生命周期(Job、Serverless)/数据获取实时性 | 难以适用 | 适用 |
能力对比 | 指标获取灵活性 | On Demand按需获取 | 被动接受,需要一些过滤器额外支持 |
能力对比 | 应用耦合性 | 应用与监控系统解耦,应用无需关心Push的对端地址、Push错误处理等 | 耦合性相比Pull较高 |
机器、人力代价 | 资源消耗 | 1. 应用暴露端口方式资源消耗低2. Exporter方式资源消耗较高 | 1. 应用推送方式资源消耗低2. Agent方式资源消耗较低(可同时采集多套系统) |
机器、人力代价 | 安全性保证 | 工作量大,需要保证应用暴露端口的安全性以及Exporter端口的安全性,容易被DDos攻击或者出现数据泄露 | 低,Agent与服务端一般都进行带有加密、鉴权的数据传输 |
机器、人力代价 | 核心运维消耗 | 1. Pull Agent稳定性与扩容2. 服务端稳定性与扩容3. 服务发现系统稳定性4. Exporter稳定性与扩容5. 网络连通性保障(反向连通性,跨集群、网络ACL) | 1. Push Agent稳定性2. 服务端稳定性与扩容3. 配置中心稳定性与扩容(可选)4. 网络连通性保障(正向连通性,较简单) |
四 原理与架构对比
如上图所示,Pull模型数据获取的核心是Pull模块,一般和监控的后端一起部署,例如Prometheus,核心组成包括:
Push模型相对比较简单:
小结:纯粹从部署复杂性上而言,在中间件/其他系统的监控上,Pull模型的部署方式太过复杂,维护代价较高,使用Push模式较为便捷;应用提供Metrics端口或主动Push部署代价相差不大。
在扩展性上,Push方式的数据采集天然就是分布式的,在监控后端能力可以跟上的时候,可以无限的横向扩展。相比之下Pull方式扩展较为麻烦,需要:
相信反应快的同学已经看出来,这种分布式的方式还是有一些问题:
存活性是监控所需要做的第一件也是最基础的工作,Pull模式监控目标存活性相对来说非常简单,直接在Pull的中心端就知道能否请求到目标端的指标,如果失败也能知道一些简单的错误,比如网络超时、对端拒绝连接等。
Push方式相对来说就比较麻烦,应用没有上报可能是应用挂了,也可能是网络问题,也可能是迁移到了其他的节点上了,因为Pull模块可以和服务发现实时联动,但Push没有,所以只有服务端再和服务发现交互才能知道具体失败的原因。
数据齐全度这个概念在大型的监控系统中还是非常重要的,比如监控一千个副本的交易应用的QPS,这个指标需要结合一千个数据进行叠加,如果没有数据齐全度的概念,若配置QPS相比降低2%告警,由于网络波动,超过20个副本上报的数据延迟几秒,那就会触发误报。因此在配置告警的时候还需要结合数据齐全度数据进行综合考虑。
数据齐全度的计算也一样是依赖于服务发现模块,Pull方式是按照一轮一轮的方式进行拉取,所以一轮拉取完毕后数据就是齐全的,即使部分拉取失败也知道数据不全的百分比是多少;
而Push方式由每个Agent、应用主动Push,每个客户端的Push间隔、网络延迟都不一样,需要服务端去根据历史情况计算数据齐全度,相对代价比较大。
在实际场景中,短生命周期/Serverless的应用也有很多,尤其是对成本友好的情况下,我们会大量使用Job、弹性实例、无服务应用等,例如渲染型的任务到达后启动一个弹性的计算实例,执行完毕后立马销毁释放;机器学习的训练Job、事件驱动的无服务工作流、定期执行的Job(例如资源清理、容量检查、安全扫描)等。这些应用通常生命周期极短(可能在秒级或毫秒级),Pull的定期模型极难去监控,一般都需要使用Push的方式,由应用主动推送监控数据。
为了应对这种短生命周期的应用,纯Pull的系统都会提供一个中间层(例如Prometheus的Push Gateway):接受应用主动Push,再提供Pull的端口给监控系统。但这就需要额外多个中间层的管理和运维成本,而且由于是Pull模拟Push,上报的延迟会升高而且还需要即使清理这些立即消失的指标。
从灵活性上来讲,Pull模式稍微有一些优势,可以在Pull模块配置到底想要哪些指标,对指标做一些简单的计算/二次加工;但这个优势也是相对的,Push SDK/Agent也可以去配置这些参数,借助于配置中心的存在,配置管理起来也是很简单的。
从耦合度上讲,Pull模型和后端的耦合度要低很多,只需要提供一个后端可以理解的接口即可,具体连接哪个后端,后端需要哪些指标等不用关心,相对分工比较明确,应用开发者只需要暴露应用自己的指标即可,由SRE(监控系统管理者)来获取这些指标;Push模型相对来说耦合度要高一些,应用需要配置后端的地址以及鉴权信息等,但如果借助于本地的Push Agent,应用只需要Push本地地址,相对来说代价也并不大。
从整体成本上讲,两种方式总体的差别不大,但从归属方角度来看:
从运维角度上讲,相对而言Pull模式的代价要稍高,Pull模式需要运维的组件包括:各类Exporter、服务发现、PullAgent、监控后端;而Push模式只需要运维:Push Agent、监控后端、配置中心(可选,部署方式一般是和监控后端一起)。
目前开源方案,Pull模式的代表Prometheus的家族方案(之所以称之为家族,主要是默认单点的Prometheus扩展性受限,社区有非常多Prometheus的分布式方案,比如Thanos、VictoriaMetrics、Cortex等),Push模式的代表InfluxDB的TICK(Telegraf, InfluxDB, Chronograf, Kapacitor)方案。这两种方案都有各自的优缺点,在云原生的大背景下,随着Prometheus在CNCF、Kubernetes带领下的大火,很多开源软件都开始提供Prometheus模式的Pull端口;但同时还有很多系统本身设计之初就难以提供Pull端口,这些系统的监控相比而言使用Push Agent方式更为合理。
而应用本身到底该使用Pull还是Push一直没有一个很好的定论,具体的选型还需要根据公司内部的实际场景,例如如果公司集群的网络很复杂,使用Push方式较为简单;有很多短生命周期的应用,需要使用Push方式;移动端应用只能用Push方式;系统本身就用Consul做服务发现,只需要暴露Pull端口就可以很容易实施。
所以综合考虑情况下对于公司内部的监控系统来说,应该同时具备Pull和Push的能力才是最优解:
SLS目前支持日志(Log)、时序监控(Metric)、分布式链路追踪(Trace)的统一存储和分析。对于时序监控方案是兼容Prometheus的格式标准,提供的也是标准的PromQL语法。面对数十万SLS的用户,应用场景可能会千差万别,不可能用单一的Pull或Push来对应所有客户需求。因此SLS在Pull和Push的选型上SLS并没有走单一路线,而是兼容Pull和Push模型。此外对于开源社区和Agent,SLS的策略是完全兼容开源生态,而非自己去造一个闭合生态:
相比VMAgent、Prometheus这类Pull Agent以及原生Telegraf,SLS额外提供了最迫切的Agent配置中心和Agent监控能力,可以在服务端去管理每个Agent的采集配置以及监控这些Agent的运行状态,尽可能降低运维管理代价。 因此实际使用SLS进行监控方案的搭建会非常简单:
本文主要介绍了监控系统中最纠结的Pull or Push选择问题,笔者结合数年的实际经验以及遇到的各类客户场景对Pull和Push的各类方向进行了比对,仅供大家在监控系统建设过程中参考,也欢迎大家留言和讨论。
Copyright© 2013-2020
All Rights Reserved 京ICP备2023019179号-8