【Prometheus】监控系统概述

Posted by 王天一 on 2019-06-08

现在开始一个新的系列,【Prometheus】,主要参考《深入浅出Prometheus》,基本为其读书笔记加上部分自己的理解

概览

在本系列中,监控系统特指对数据中心的监控,包括硬件和软件的监控和告警

监控系统的作用:

  1. 实时监控。提供硬件和软件的运行状态展示
  2. 告警。符合预设告警阈值则通过多种方式发送告警信息
  3. 辅助决策。大数据监控不仅提供实时状态展现,更能帮助故障回溯和预测风险

根据程序设计的角度来分类,监控的种类如下,每种监控都涉及不同的监控指标,不同的收集方式,具体在下文分析

基础资源监控

网络

  1. 网络性能监控。涉及网络监测、网络实时流量监控(网络延迟、访问量、成功率等)和历史数据统计、汇总和历史数据分析
  2. 网络攻击检查。针对内网或者外网的网络攻击如 DDoS 攻击等,通过分析异常流量来确定网络攻击行为
  3. 设备监控。对数据中心的网络设备监控,如路由器、防火墙、交换机,通过SNMP协议收集

服务器

监控分类:

  1. 主机监控。服务器硬件来源于不同厂商,需要获取不同厂商的服务器硬件信息
  2. 虚拟机监控。不同的操作系统如 Windows、Linux,采集软件需要做到跨平台运行以获取对应的指标
  3. 容器监控。兼容各种虚拟化环境如虚拟机(KVM、VMware、Xen)及容器(Docker、rkt)

采集方式有两种:

  1. 主机监控。IPMI(Intelligent Platform Management Interface,智能平台管理接口)实现。IPMI是一种标准开放的硬件管理接口,不依赖于操作系统,可以提供服务器的风扇、温度、电压等信息
  2. 虚拟机监控。一是内置客户端。在每台机器上安装采集客户端。二是在虚拟机环境下通过Xen API、VMware Vcenter API获取监控数据
  3. 容器监控。Docker API或针对不同服务/中间件开发的采集器exporter作为一个运行容器进行导出

采集指标:

  1. CPU。CPU使用量、用户态百分比、内核态百分比、每个CPU的使用量、等待队列长度、I/O等待百分比、CPU消耗最多的进程、上下文切换次数、缓存命中率
  2. 内存。使用量、剩余量、内存占用最高的进程、交换分区大小、缺页异常数
  3. 网络I/O。涉及每个网卡的上行流量、下行流量、网络延迟、丢包率
  4. 磁盘I/O。涉及硬盘的读写速率、IOPS、磁盘用量、读写延迟

中间件监控

中间件监控需要针对不同中间件的特点和属性分别监控,目前并没有统一的标准和规范

例如,针对 Kafka 的性能监控通常需要采集 Kafka 集群的 Topic 个数、Broker 数据分区数量、日志 Offset值和生产消费流量等指标

针对 Redis的性能监控通常需要采集 Redis 的内存使用量、连接数和缓存命中率等指标

解决方案通常是分别开发一个数据收集 Agent,该 Agent 将采集中间件的性能指标并将其统一转化成 JSON、文本或者其他监控系统能识别的数据格式,然后汇总到监控中心

Prometheus针对不同的中间件开发了对应的监控代理,例如Kafka exporter、MySQL server exporter、Apache exporter、Redis exporter等exporter,它们负责采集这些中间件的特定指标,并提供HTTP查询接口

应用程序监控(APM)

采集的方法是将采集器运行在容器内,导出所有容器运行的数据

  1. 调用链跟踪。从用户发送请求到后端API服务,以及API服务和关联的中间件或者其他组件之间的调用,构建出一个完整的调用拓扑结构
  2. 性能监控。监控组件内部方法的调用层次(Controller→Service→DAO),获取每个函数的执行耗时,从而为性能调优提供数据支撑。还能截获TCP、HTTP网络请求,从而获得执行耗时最长的方法和SQL语句、延迟最大的API等信息
  3. 运行状态监控。根据业务指标、日志指标、调用链指标、应用环境指标、应用集群指标、服务组件指标、线程栈和客户端体验数据等,形成全维度的指标,展示为服务运行状态

日志监控

日志监控采集日志数据(文本类型),并将这些数据汇总到日志存储和搜索引擎中,提供日志检索的 Web 接入。指标监控的对象通常都是数字,而日志监控的对象是文本数据,这就要求存储系统具备文本检索功能

下面是流行的日志监控黄金组合:

  1. Fluentd:日志采集,还有Filebeat、Flume、Fluent Bit,也有一些应用集成Log4g等日志组件直接输出日志
  2. Kafka:数据整流合并,避免突发日志流量直接冲击Logstash
  3. Logstash:日志整理,完成日志过滤、日志修改等功能
  4. Elasticsearch:日志存储和日志检索,自带分布式存储,可以将采集的日志进行分片存储
  5. Kibana:日志查询组件,负责日志展现,主要通过Elasticsearch的HTTP接口展现日志

监控系统实现

总体架构

  • 指标采集子系统。负责信息采集、过滤、汇总和存储
  • 数据处理子系统。负责数据分析、展现、预警、告警动作触发和告警

指标采集子系统

数据采集

  • 通过客户端进行数据采集。针对特定的设备和系统开发的采集器。客户端会将采集到的数据上报到监控中心节点进行汇聚存储。这种方式比较灵活,在理论上任何对象都是可以被监控的。但客户端本身需要一定的开发工作,采用侵入的方式安装客户端也存在安全和性能风险
  • 通过标准协议进行数据采集。优点是数据规范统一、普适性更广,所有Java应用都可以实现 JMX 协议,从而完成应用指标监控。但目前数据中心内的软硬件各异,设备和软件对协议的支持也不完善,在很大程度上限制了通过协议进行数据采集的能力

数据传输和过滤

  • HTTP、Socket连接进行点对点传输。如果 Agent(采集器)是一个 HTTP 服务端,那么采集中心节点会周期性调用 Agent 的接口获取数据,这种方式被称为 Pull(拉取);相反,如果 Agent是一个 HTTP客户端,它就会调用中心节点的 HTTP服务,将数据发送到中心节点,这种方式被称为Push(推送)
  • RabbitMQ、Kafka等消息中间件进行传输。使用消息中间件传输的方式在结构上充分解耦。消息中间件不仅可以将监控数据进行一定程度的持久化,而且可以对监控数据进行整流,避免突发流量冲击数据收集组件。但会造成整个系统对中间件的强依赖,如果中间件发生故障,则可能导致整个系统发生故障,并且消息中间件在安装部署及后期的运维中都比较复杂。

HTTP 传输的方式虽然有一定的耦合度,但系统可以足够简单,易于扩展和维护,大部分开源监控系统都采用这种方式

在持久化之前,通常还需要对收集的数据进行简单去重和过滤,主要有以下几个场景:

  1. 客户端重复上报数据。网络不稳定等因素
  2. 去除无用指标。客户端上报的指标通常是全集,而有些指标是系统并不关注的

数据存储

对监控数据的存储通常借助于时序数据库。监控数据的最大特点是有时间属性,每个监控数据都有一个时间维度(属性),被称为时序数据,展现了一个物体的某些特征在一段时间内的变化情况

时序数据的特点:

  • 一次性写入多次读取。时序数据通常不会修改更新,一旦存入,则后期只会对数据进行查询操作
  • 数据流持续平稳且量大。时序数据量往往和采集点的数据量成正比,不会出现业务系统流量突增的情况,并且数据流是持续稳定的,通常间隔一个稳定的采集周期来获取数据。但存储的数据量会慢慢变得非常大。
  • 查询方式以时间为维度,数据查询通常会指定一段时间,并且热数据通常都是最新采集的数据。在实际场景中通常查询最近几个小时的监控数据

所以,与关系型数据库采用B+树不同,时序数据库通常采用LSM树,提供更好的写性能。因为LSM树存储框架实现的思路较简单,其先在内存中保存数据,再定时刷到磁盘,实现顺序IO操作,通过定期合并文件减少数据冗余;文件有序,保证读取操作相对快速。适用于写多、读相对少(或较多读取最新写入的数据,该部分数据存在内存中,不需要磁盘IO操作)的业务场景

数据处理子系统

数据查询

通过展现层(浏览器或者客户端)多维度展现实时数据和历史数据。实时数据查询严格要求数据的准确性和实时性,查询接口需要迅速响应

另外,可以通过一些Web工具,把后端分析的数据以可视化的方式展现。比如:

  • 折线图能够很好地展现数据变化的趋势
  • 饼状图能更好地展现系统中各个子模块的占比
  • 柱状图的优势在于对数据的对比

数据分析

  • 性能分析:分析某个应用在特定时间段内的资源消耗情况,可以将应用按照资源消耗的特点分类。当应用程序出现性能问题时,要能够通过性能分析确定故障点,并在故障发生后回溯故障发生的原因
  • 关联分析:每个监控数据都存在多个维度,通过关联分析可以找出数据之间的关联。在 APM 监控中,通过相同 TraceId 的关联,可以构建出程序的调用链信息,这样不仅可以分析出组件之间的调用关系,还可以分析出每个调用的耗时,从而优化系统性能
  • 趋势分析:对采集数据指标进行分析,再结合平均数算法、指数平滑算法、Holt线性趋势算法或其他机器学习模型如自回归积分滑动平均,分析时序数据内在的周期性,得出未来的变化趋势。可以用于实时资源调度、预分配资源,还可以辅助数据中心的硬件采购

基于规则告警

利用已经采集的监控数据,匹配用户自定义的多维度告警规则,如果满足,则触发相应规则的告警。例如,性能告警规则一般是设定某个阈值、触发次数和告警行为

还有一些告警属于异常告警,例如服务器宕机、网络不通等情况,通常不需要设定告警规则。如果某个告警规则被触发,则在接下来的一段时间内,为避免相同的告警被多次触发,需要进行告警抑制

对告警的处理,会按照用户预先设定的告警动作执行对应的操作,通常会发送短信、邮件或者触发用户定义的 webhook。高级的告警处理可以执行告警的恢复脚本,先在系统中预先设定一些常用的恢复脚本,系统能够根据发生的不同事件,判断并使用不同的脚本处理告警事故