Please enable Javascript to view the contents

监控告警系统概述

 ·  ☕ 6 分钟

监控系统的难点在于,存储大容量时序数据,提供高性能的查询能力;告警系统的难点在于,设计高效的告警引擎,实现灵活的告警升级机制。最近一直在跟踪监控告警系统,本篇主要是整理监控告警相关的一些概念、组件,调研方案。

1. 监控告警系统的组成

对于监控告警的定义,每个人都会有一些自己的理解。我的理解是: 监控是将发生的事情记录下来,以供事前事后分析;告警是当非预期的事情发生时,能够及时告知。

如上图,一个监控告警系统会包含如下几个部分:

Agent - 负责采集,并将关注的指标数据上报
Storage - 负责存储 Agent 上报的数据
Alarm - 负责检测上报的数据是否达到预设的阈值
Notification - 负责将告警发送给指定的接收人

2. 采集

2.1 采集的数据格式

不同于传统的关系型数据库,监控指标的数据实际上是基于时间的抽样,适合使用时序数据库进行存储。目前主流的时序数据库,大多数都是采用 Metric 加 Tag 的方式,来描述一条监控指标,Tag 的作用是标记指标的维度信息。下面是一条监控数据:

api_http_requests_total{path="/home",status=200,method="GET",instance="10.10.12.11"}

其中,时序的名字为 api_http_requests_total,标签为 pathstatusmethodinstance,时序名字和标签共同决定了一个时序。

因此,我们才可以根据 status Tag 统计状态码的分布,根据 method Tag 统计请求方法的比例。

2.2 采集组件 Exporter

Exporter 通过 http 服务暴露指标数据给采集方抓取,比如暴露给 Pormetheus。Exporter 不会存储历史数据,只会等待采集方抓取时,提供最近一次的数据。

在开源社区中,已经有各种主机、中间的 Exporter 可供使用,非常方便。

2.3 AllInOne 的 Exporter - Telegraf

使用 Exporter 让人烦恼的地方在于,主机有一个 Exporter、MySQL 有一个 Exporter,如果运维组件很多,Exporter 的维护成本很高。

Telegraf 采用了类似 Logstash 的 Pipeline 方式,使用 input、output 以及 processor 插件组装采集能力。因此,我们只需要使用一个 Telegraf + 多种配置文件就可以替代多种 Exporter,大大降低了维护的成本。

但另一方面,由于 Telegraf 包含的采集器太多,会导致可执行文件过大。因此,有时我们也会裁剪 Telegraf,去掉用不上的部分,以维持可执行文件足够小。

2.4 Pushgateway 补充推送场景

Exporter 只是提供 http 接口,被动等待采集。但是有些场景下,需要主动推送指标数据,比如短生命周期的 Job 任务,等不到采集方抓取就被销毁了。这时,Pushgateway 就能够接受 Job 主动推送的监控数据,再等待采集方的抓取。

另外一个场景是,如果所有 Exporter 都在采集方配置采集端点,会导致采集方配置难以维护。因此,也可以使用 Pushgateway 提前将数据聚合,再提供给采集方。这样可以减少采集方维护采集端点的成本。

还有一个场景是,Exporter 与采集方的网络不可靠时,需要通过 Pushgateway 进行中转。

3. 存储

3.1 时序数据库的特征

监控数据的特征是与时间序列强相关,因此需要使用的是时序数据库。市面上已经有大量开源的产品可以使用,InfluxDB、OpenTSDB、M3DB 等,这些时序数据库碰到的核心问题是 垂直写,水平读

如上图所示,我们在采集指标时,每次采集的是某一个时刻的数据,但是在查询时却又基于某一个 Metric 指标进行统计,基于 Tag 进行过滤查询。这种使用方式,给时序数据库的设计和实现带来了挑战。既要能快速存储大量垂直指标数据,又要能够快速查询水平数据。

3.2 Prometheus

Prometheus 是前 Google 工程师在 Soundcloud 开源的监控告警项目。目前,大部分公司都会采用 Pormetheus 作为监控告警工具。

Prometheus 的特点是:既有数据存储,也有告警引擎。因此,只需要部署一套 Pormetheus 就可以开箱即用,满足大部分的监控场景。

Prometheus 的问题是:服务单点,使用文件配置规则。当单点的 Prometheus 重启或抓取 Exporter 数据故障时,都会导致监控数据缺失。因此,生产环境下,有时也会采用两套 Prometheus 同时抓取 Exporter 指标数据的方案。

3.3 为啥要远端存储

Prometheus 为了降低自身的复杂度,使用了本地存储,足以满足大部分用户规模的监控场景,但无法满足对长期数据的查询需求。因此,在业务规模较大时,我们会将 Prometheus 的本地数据作为临时数据,而将长期数据转存到远端。

最终,针对近期数据的告警查询,使用的是 Prometheus; 而历史数据的统计查询,使用的是远端存储。这里介绍三种远端存储方案:

  • InfluxDB

InfluxDB 在时序数据库排名中,长期占据第一。InfluxDB 的集群模式需要收费,单例模式源码开源。我们可以将 Prometheus 的 remote write 到 InfluxDB,当 Grafana 从 Prometheus 进行长期查询时,使用 InfluxQL 查询 InfluxDB,进行短期查询时,使用 PromQL 查询 Prometheus。

  • VictoriaMetrics

VictoriaMetrics 也分为单机版和集群版。VictoriaMetrics 并不是 100 % 兼容 PromQL 查询语句。如果没有用到告警,单机版的 VictoriaMetrics 可以直接用于替换 Prometheus,也可以作为 Prometheus 的远端存储使用。VictoriaMetrics 也提供了集群模式,包含 vmagent、vmstorage、vminsert、vmselect、vmalert 组件,实现了一整套高可用、存储可扩展的监控告警方案。

  • Thanos

Thanos 的定位是监控终结者,得到社区大力推荐。Thanos 包含 Querier、Slidercar、Store、Compactor 组件,通过在 Prometheus 上挂载 Sidecar 上报数据并提供查询能力。Thanos 会将监控数据存储到 S3,同时 Compator 还会对数据进行采样。这样的好处是,在查询长期数据时,可以先查 S3 采样的数据展示结果,而不是读取全量数据。

4. 分析

当指标上报、数据进入时序数据库之后,我们就需要不断地查询分析,指标是否符合预期,或者查看长期数据。

数据检测的过程就是不断地调用接口查询的过程。如果用代码实现,就是一个循环。但其中有很多的细节需要考虑:

  • nodata

没有数据的原因可能是服务没有上报数据,也有可能是上报链路异常,还可能是查询时异常。这种情况下,如何处理?常见的有两种处理方式:1,nodata 上报特殊数值;2,单独实现 nodata 的检测。

  • 大量检测

当配置的每分钟检测规则达到一定数量级时,单个时序数据库扛不住。这里就会衍生出一些优化的方案,比如使用集群分担查询、在检测时刻 BIAS 几秒错峰等。还有一种方案是,使用 Redis 等高性能数据库临时存储短期指标数据,用于告警检测。

5. 告警

分析阶段会产生大量告警事件,这些事件如果直接推送给用户,将会产生大量垃圾信息。告警模块的目的是为了提高通知的价值密度,让用户能够准确高效地获知线上故障。

  • 告警规则的管理

告警规则提供了分析阶段需要的查询语句。怎样高效地管理这些告警规则,是告警系统需要解决的问题之一。

  • 告警实例的管理

在监控数据达到告警规则阈值时,就会产生一个告警实例。我们需要对告警实例进行管理。告警实例状态会发生流转,正在告警、恢复、未处理。

  • Alertmanager

社区中很多方案都会使用 Prometheus + Alertmanager 的告警组合,使用 helm 部署 Prometheus 时,也可以很方便地部署全套方案。

Prometheus 提供的告警引擎,在检测到异常时,会将告警推送给 Alertmanager 。Alertmanager 会根据路由配置,将告警发送给指定的接收人。Altermanager 也是采用文件配置规则。

6. 参考


微信公众号
作者
微信公众号