监控系统 prometheus

85 阅读5分钟

监控系统典型架构

image.png

告警引擎

告警引擎通常有两种架构,一种是数据触发式,一种是周期轮询式。

数据触发式,是指服务端接收到监控数据之后,除了存储到时序库,还会转发一份数据给告警引擎,告警引擎每收到一条监控数据,就要判断是否关联了告警规则,做告警判断。因为监控数据量比较大,告警规则的量也可能比较大,所以告警引擎是会做分片部署的,即部署多个实例。这样的架构,即时性很好,但是想要做指标关联计算就很麻烦,因为不同的指标哈希后可能会落到不同的告警引擎实例。注:分片的常见做法是根据指标标识做哈希。

周期轮询式,架构简单,通常是一个规则一个协程,按照用户配置的执行频率,周期性查询判断即可,因为是主动查询的,做指标关联计算就会很容易。像 Prometheus、Nightingale、Grafana 等,都是这样的架构。

生成事件之后,通常是交给一个单独的模块来做告警发送,有了专门处理这类需求的产品,最典型的比如 PagerDuty

数据展示

Grafana 采用插件式架构,可以支持不同类型的数据源,图表非常丰富

监控数据可视化,通常有两类需求,一个是即时查询,一个是监控大盘(Dashboard)

拉模式 与 服务发现

time.geekbang.org/column/arti… image.png

image.png

  • 拉模式需要有很好的服务发现机制

Prometheus 支持各种服务发现机制,尤其是基于 Kubernetes 的服务发现机制,是最常见的。如果服务没有部署在 Kubernetes 中,而是部署在传统物理机或虚拟机上,这个时候就需要使用 Consul 之类的服务发现机制。但如果在监控体系建设之前,服务没有接入注册中心,为了满足监控需求而接入注册中心,用户会觉得成本太高。此时推模式就有了用武之地,这就是很多公司的自研服务都使用推模式发送监控数据的原因。

Prometheus 内置了多种服务发现机制,最常见的有四种。

  • 基于配置文件的发现机制:这种方式看起来很低端,其实非常常用,因为可以配合配置管理工具一起使用,非常方便。使用配置管理工具批量更新配置,然后让监控系统重新加载一下就可以了,比较丝滑。
  • 基于 Kubernetes 的发现机制:Kubernetes 中有很多元信息,通过调用 kube-apiserver,可以轻易拿到 Pod、Node、Endpoint 等列表,Prometheus 内置支持了 Kubernetes 的服务发现机制,让这个过程变得更简单,Prometheus 基本成为了 Kubernetes 监控的标配。
  • 基于公有云 API 的发现机制:比如要监控公有云上所有的 RDS 服务,一条一条配置比较麻烦,这个时候就可以基于公有云的 OpenAPI 做一个服务发现机制,自动拉取相关账号下所有 RDS 实例列表,大幅降低管理成本。
  • 基于注册中心的发现机制:社区里最为常用的是 Consul,典型场景是 PING 监控和 HTTP 监控,把所有目标注册到 Consul 中,然后读取 Consul 生成监控对象列表即可。

architecture

prometheus.io/docs/introd…

image.png

Prometheus的基本原理是通过HTTP协议周期性抓取被监控组件的状态

golang 项目接入

cloud.tencent.com/document/pr…


package main

import (

"net/http"

"github.com/prometheus/client_golang/prometheus/promhttp"

)

func main() {

http.Handle("/metrics", promhttp.Handler())

http.ListenAndServe(":2112", nil)

}

storage

prometheus.io/docs/promet…

blog.devops.dev/the-design-… image.png

The current block for incoming samples is kept in memory and is not fully persisted. It is secured against crashes by a write-ahead log (WAL) that can be replayed when the Prometheus server restarts. Write-ahead log files are stored in the wal directory in 128MB segments. These files contain raw data that has not yet been compacted; thus they are significantly larger than regular block files. Prometheus will retain a minimum of three write-ahead log files. High-traffic servers may retain more than three WAL files in order to keep at least two hours of raw data.

Note that a limitation of local storage is that it is not clustered or replicated. Thus, it is not arbitrarily scalable or durable in the face of drive or node outages and should be managed like any other single node database. The use of RAID is suggested for storage availability, and [snapshots](prometheus.io/docs/promet…) are recommended for backups. With proper architecture, it is possible to retain years of data in local storage.

Compaction

The initial two-hour blocks are eventually compacted into longer blocks in the background.

Compaction will create larger blocks containing data spanning up to 10% of the retention time, or 31 days, whichever is smaller.

数据量问题

要存储的指标数据量是巨大的。以下是一些可以缓解这个问题的策略

(1)数据编码和压缩。数据编码和压缩可以显著减小数据的大小。我们来看一个简单的例子。如图17-19所示,1610087371和1610087381之间只差10秒,差值“10”只需要用4比特表示而无须保存32位的完整时间戳。所以,与其存储绝对值,不如存储值的增量以及一个基础值,比如1610087371、10、10、9、11。

(2)向下采样(Downsampling)。向下采样是把高分辨率数据转换为低分辨率数据的过程。它用于减少整体的硬盘使用量。因为我们的数据保存期是1年,所以可以向下采样老数据。例如,我们允许工程师和数据科学家为不同的指标定义规则。下面是一个例子。•保存期:1天,不采样。•保存期:30天,向下采样到1分钟的分辨率。•保存期:1年,向下采样到1小时的分辨率。

(3)冷存储。冷存储指的是几乎不会被用到的不活跃数据的存储。冷存储的成本要低很多。