面试场景题系列:设计指标监控和告警系统

在本文中,我们将探讨可扩展的指标监控和告警系统的设计。理解基础设施的状况对维持其可用性和可靠性至关重要。

图-1展示了一些市面上最流行的商用和开源的指标监控和告警服务。

图-1

1.场景边界界定

为了便于展开设计以及考虑通用性,监控和告警需求如下:

(1)流量大。

•1亿日活用户。

•1000个服务器池,每个池有100台机器,每台机器上有100个指标,总共有1000万个指标。

•数据保留12个月。

•假设每天触发50000个告警。

(2)可以监控一系列指标,包括但不限于:

•CPU使用率。

•请求数量。

•内存使用率。

•异常数量。

•消息队列里的消息数量。

(3)系统应该是可扩展的,以便容纳更多的指标、告警等。

(4)系统应该高度可靠,以避免错失关键告警。

(5)值班开发者应该可以快速接收到告警,从而及时开展调查。

2.高层级设计

在本节中,我们会讨论系统的基本原理、数据模型和高层级设计。

2.1 基本原理指标

监控和告警系统通常包含5个组成部分,如图-2所示。

•数据收集:从不同来源收集指标数据。

•数据传输:把数据从源头传输到指标监控系统。

•数据存储:组织和存储传入的数据。

•告警:引起工程师的注意,使其调查问题或者触发自动修复。告警系统必须能将通知发到不同的通信渠道。

•可视化:通过图、表等来展示数据。一图胜千言。当数据以可视化方式展示时,我们更容易发现模式、趋势或者问题。

图-2

2.2 数据模型指标

数据通常以时间序列(Time-series)的格式记录,它展示了数据随着时间的变化。这里有两个例子。

例1:生产环境的服务器实例i631在20:00的CPU负载是怎样的(见图-3)

图-3

例2:所有Web服务器在最近的10分钟内的平均CPU负载是多少?在存储中,我们可能有如下的数据。

每个时间序列包括如表-1所列的数据指标描述:

数据访问模式

在图-4中,y轴代表时间序列名字和标签的组合,x轴表示这个时间序列被记录时的时间点。如你所见,有许多时间序列在同一时间点被记录,1.1节提到,每天大概有1000万个运行指标被写入,所以毋庸置疑这个流量是重写入(Write-heavy)的。同时,查询通常查的是某一个时间区间的多个时间序列,例如图-4中的高亮部分。如果你想查询一个服务池(Service Pool)中所有机器的报错数据,你就需要聚合多个时间序列的样本。因为可视化和告警服务都会将查询请求发送给查询服务,所以这个系统也是重读取(Read-heavy)的。如图-4所示,数据看起来像是一个巨大的矩阵,在横纵两个方向都可以无限增长。

图-4

数据存储系统

有了对数据访问模式的清晰理解,我们就可以选择数据存储系统了。

我们可以把数据存储在关系型数据库中,但是会遇到各种挑战,比如写性能和可扩展性方面的问题,主要是因为它们并没有针对典型的时间序列工作负载(随时间变化的数据)做优化。另一方面,有几个非关系型数据库可以很高效地处理时间序列数据。

OpenTSDB是一个分布式时间序列数据库,但它是基于Hadoop和HBase的,运行Hadoop/HBase集群会增加复杂性。Bigtable也可以用于处理时间序列数据。Twitter使用MetricsDB,而亚马逊提供了Timestream作为时间序列数据库。

根据DB-Engines的排名,两个最流行的时间序列数据库是InfluxDB和Prometheus,它们都被设计来存储大量的时间序列数据并快速对数据进行实时分析。这两个数据库主要依赖内存缓存和硬盘存储,并且在数据的持久性和性能方面表现出色。我们来看一个例子。如图-5所示,一个有8核和32GB内存的InfluxDB每秒可以处理超过250,000次的写操作!

图-5

2.3 高层级设计

图-6展示了高层级的设计示意图。

图-6

•指标来源:可以是应用服务器、SQL数据库、消息队列等。

•指标收集器:收集指标数据,并把数据写入时间序列数据库。

•时间序列数据库:把指标数据存储为时间序列。

•查询服务:简化了从时间序列数据库查询和获取数据的过程。

•告警系统:将告警通知发送到各个目的地。

•可视化系统:用各种图表来展示指标。

让我们接着深入探讨一些组件。

3. 设计继续深入

在系统设计面试中,候选人要能深入解释一些关键组件或者流程。在本节,我们会详细讨论如下话题。

•指标数据的收集。

•扩展系统。

•查询服务。

•存储层。

•告警系统。

•可视化系统。

3.1 指标数据的收集

首先,我们看一下指标数据收集流程。图-7高亮显示了系统中的指标数据收集部分。

图-7

拉模型vs.推模型

有两种收集指标数据的方法:拉或推。选择正确的数据收集方法,是在设计的早期就要做的重要决定。

(1)拉模型。图-8展示了采用拉模型通过HTTP请求收集数据。我们有专门的指标收集器,可以定期从运行的应用中拉取指标值。

在这个方法中,指标收集器需要知道服务端点的完整列表,以便爬取。我们可以在“指标收集器”服务器上用一个文件来存储DNS/IP地址信息。但是在大型系统中,服务器可能会被频繁添加或移除,因此很难维护这样的列表文件,并且我们希望确保指标收集器不会丢掉任何来自新服务器的指标数据。好消息是,我们通过服务发现功能可以得到一个可靠、可扩展和可维护的解决方案。服务发现组件是Kubernetes、ZooKeeper等提供的。在服务发现组件中注册服务的可用性,然后指标收集器就可以查询服务发现组件来获取可用服务列表以便爬取。

图-8

服务发现组件中包含了关于何时和从何处收集指标的配置规则,如图-9所示。

图-9

图-10详细解释了拉模型。

图-10

•指标收集器从服务发现组件获取Web服务器的配置元数据(比如爬取时间间隔、IP地址、超时时间等)。

•指标收集器通过HTTP/metrics端点来拉取指标数据。为了暴露/metrics端点,通常需要在Web服务器上安装客户端库(比如SDK)。

(2)推模型。如图-11所示,多个指标来源(如Web服务器、数据库集群等)直接将数据发给指标收集器。

图-11

这个简单的推模型有一个缺点,它可能会给指标收集器带来巨大的流量。这可能成为一个瓶颈。解决方案之一是在应用服务器(如Web服务器、数据库服务器等)上安装代理(agent)。代理是运行在应用服务器上的软件。它从应用服务器上收集各种指标数据并进行处理,然后把它们推送给指标收集器。如果推送的流量大,代理就会进行调整以避免指标收集器被压垮。如图-12所示,指标收集代理安装在应用服务器上。Palo Alto Networks采用了类似的方法。

图-12

采用哪一种模型更好呢?就像生活中的许多事一样,这没有一个明确的答案。在现实中,这两种模型都被广泛应用。

•采用拉模型的例子:Prometheus。

•采用推模型的例子:Amazon CloudWatch和Graphite。在面试中,更重要的是了解每个方法的优缺点,而不是选出一个优胜者。表-2比较了拉模型和推模型的优缺点。

表-2

3.2 扩展系统

我们来仔细看看指标收集器和时间序列数据库。无论你使用什么模型(推或者拉),指标收集器都会收集巨量的数据。原先设计(见图-13)中的指标收集器可扩展性不太好,这是因为:

•指标收集器也负责数据处理,它很容易被压垮。指标收集器应该尽可能简单并保持低延时,以便最大限度地降低数据丢失的风险。

•如果时间序列数据库不可用,则要么有丢失数据的风险,要么指标收集器需要将数据存储在临时数据存储中,并在稍后重新发送该数据。

图-13

了减轻这两个问题的影响,我们引入了队列组件,如图-14所示。

图-14

在这个设计中,指标收集器将指标数据发送给队列系统,比如Kafka,然后消费者或者流处理服务(如Apache Storm、Flink和Spark)处理数据并将其推送给时间序列数据库。这个方法有如下优点。

•Kafka可以用作高可靠和可扩展的分布式消息平台。

•它解耦了数据收集和数据处理服务。

•当数据库不可用时,将数据保留在Kafka中,能容易地避免数据丢失。

•不会给指标收集器施压。

通过Kafka扩展

有多种方法可以利用Kafka内置的分区机制来扩展我们的系统。

•基于吞吐量的需求配置分区数量。

•可以按指标名字分区,以便消费者按名字来做聚合(见图-15)。

•可以进一步按标签来分区。

•可以对指标分类和排定优先级,以便先处理重要的指标。

图-15

3.3 查询服务

查询服务由查询服务器集群提供。它们访问时间序列数据库,并处理来自可视化系统或者告警系统的请求。使用一组专有的查询服务器把时间序列数据库与客户端(可视化和告警系统)解耦,使得我们无论何时需要都可以更换时间序列数据库或者可视化和告警系统。为了减少时间序列数据库的负载并使查询服务更高效,这里添加了缓存服务器来存储查询结果,如图-16所示。

图-16

时间序列数据库查询语言

大部分流行的指标监控系统(比如Prometheus和InfluxDB)不使用SQL,而是创建了自有的查询语言。这么做有几个原因。最重要的一个原因是使用SQL语句来查询时间序列数据很困难。例如,influxdata博客上的文章“Why We’re Building Flux,a New Data Scripting and Query Language?”说,使用SQL计算指数滑动平均值可能需要写这些代码:

但是,如果在InfluxDB中使用Flux语言,只需要写下面这几行代码即可,因为Flux是专门针对时间序列分析做过优化的语言:

3.4 存储层

缓存最近的数据

根据Facebook的论文“Gorilla:A Fast,Scalable,In-Memory Time Series Database”,在所有对运营数据存储的查询中,至少有85%针对的是过去26小时以内收集的数据。如果我们缓存最近的时间序列数据,就可以显著提升插入和查询速度。如图-17所示,我们在时间序列数据库之上添加了一个缓存层。时间序列数据库的存储引擎通常包括下面4个组成部分:预写日志(Write Ahead Log,WAL)、缓存、时间结构合并树(Time-Structured Merge Tree,TSM树)和时间序列索引(Time Series Index,TSI)。存储引擎的设计需要专门的领域知识,不在本文的讨论范围内。感兴趣的读者可以阅读Influx DB存储引擎的设计文档“InfluxDB Storage Engine”。

图-17

聚合

为了确保查询服务提供低延时的查询且减少要存储的数据量,我们允许工程师或者数据科学家按特定的粒度(1秒、10秒、1分钟、1小时等)来灵活聚合和存储时间序列数据。Uber也使用了类似的方法。

图-18

空间优化

如1.1节中所述,要存储的指标数据量是巨大的。以下是一些可以缓解这个问题的策略。

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

图-19

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

•保存期:1天,不采样。

•保存期:30天,向下采样到1分钟的分辨率。

•保存期:1年,向下采样到1小时的分辨率。

3.5 告警系统

现在,我们看一下告警系统,如图-20所示。

告警的流程如下:

1.将规则配置文件加载到缓存服务器。规则以配置文件的形式保存在硬盘上。YAML是用来定义规则的一种常用格式。下面是一个告警规则的例子:

2.告警管理器从缓存服务器获取告警规则。

3.基于所配置的告警规则,告警管理器按照预定的间隔请求查询服务。如果监控的指标超过了阈值,就会触发告警事件。告警管理器也负责如下事项:

•过滤、合并和删除重复告警。图-21展示了对同一个实例(实例1)触发的告警进行合并的例子。

图-21

•访问控制。为了避免人为错误并保证系统安全,只允许获得授权的人访问特定的告警管理操作。

•重试。告警管理器检查告警的状态并确保至少发送了一次通知。

4.告警存储是一个键值数据库(比如Cassandra),它保存所有告警的状态机。它确保至少发送了一次通知。

5.合格的告警被插入Kafka。

6.告警消费者从Kafka中拉取告警事件。

7.告警消费者处理Kafka中的告警事件,并将通知发送到不同的接收端,如邮件、短信、PagerDuty或者HTTP端点。

3.6 可视化系统

可视化系统建立在数据层之上,可以基于不同的时间范围将指标展示在指标仪表板上,而将告警展示在告警仪表板上。图-22展示了一个仪表板,上面列出了如当前服务器请求、内存/CPU使用率、页面加载时间、网络流量和登录信息等指标。

图-22

4. 总结

在本文中,我们介绍了指标监控和告警系统的设计,讨论了数据收集、时间序列数据库、告警和可视化系统的高层级设计。我们还深入探讨了其中几个最重要的技术/组成部分:

•收集指标数据的拉模型和推模型。

•使用Kafka来扩展系统。

•在时间序列数据库之上添加缓存层。

•使用编码或者压缩算法来减小数据大小。

•过滤和合并告警,使得值班开发人员不会被收到的告警数量压垮。

系统经过了几轮迭代和优化,最终的设计如图-23所示。

图-23

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/946138.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Spring实现输出带动态标签的日志

版权说明: 本文由博主keep丶原创,转载请保留此块内容在文首。 原文地址: https://blog.csdn.net/qq_38688267/article/details/144851857 文章目录 背景底层原理实现方案Tag缓存实现封装注解通过AOP实现日志缓存封装行为参数通用方法实现手动…

1月第一讲:WxPython跨平台开发框架之前后端结合实现附件信息的上传及管理

1、功能描述和界面 前端(wxPython GUI): 提供文件选择、显示文件列表的界面。支持上传、删除和下载附件。展示上传状态和附件信息(如文件名、大小、上传时间)。后端(REST API 服务)&#xff1a…

微服务SpringCloud分布式事务之Seata

视频教程:https://www.bilibili.com/video/BV16P63Y3ESq 效果演示 准备的微服务项目调用的链路如下: 文字描述: gateway模块接收到请求,并发送到order订单模块order订单模块接收到请求,新增一个订单数据后发送一个…

Solon 加入 GitCode:助力国产 Java 应用开发新飞跃

在当今数字化快速发展的时代,Java 应用开发框架不断演进,开发者们始终在寻找更快、更小、更简单的解决方案。近期,Solon 正式加入 GitCode,为广大 Java 开发者带来全新的开发体验,尤其是在国产应用开发进程中&#xff…

[实用指南]如何将视频从iPhone传输到iPad

概括 将视频从 iPhone 传输到 iPad 时遇到问题?您可能知道一种方法,但不知道如何操作。此外,您要传输的视频越大,完成任务就越困难。那么如何将视频从 iPhone 传输到 iPad,特别是当您需要发送大视频文件时&#xff1f…

【一起python】银行管理系统

文章目录 📝计算机基础概念🌠 导入模块🌠定义input_card_info函数🌠 定义check_password函数🌠初始化用户字典和欢迎信息🌉 主循环🌉开户操作🌉查询操作🌉取款操作&#…

20241218-信息安全理论与技术复习题

20241218-信息安全理论与技术复习题 一、习题1 信息安全的基本属性是(D )。 A、机密性 B、可用性 C、完整性 D、上面 3 项都是 “会话侦听和劫持技术” 是属于(B)的技术。 A、 密码分析还原 B、 协议漏洞渗透 C、 应用漏洞分析与渗透 D、 D…

音视频入门基础:MPEG2-PS专题(2)——使用FFmpeg命令生成ps文件

一、错误的命令 通过FFmpeg命令可以将mp4文件转换为ps文件,PS文件中包含PS流数据。 由于PS流/PS文件对应的FFInputFormat结构为: const FFInputFormat ff_mpegps_demuxer {.p.name "mpeg",.p.long_name NULL_IF_CONFIG_SMALL…

Unity is running as administrator解决办法

每次打开Unity项目都会有这个弹窗 解决办法: 打开本地安全策略 - 安全选项 ,把 用户账户控制:以管理员批准模式运行所有管理员 用户账户控制:用于内置管理员账户的管理员批准模式 改成已启用就行

活动预告 |【Part1】Microsoft Azure 在线技术公开课:数据基础知识

课程介绍 参加“Azure 在线技术公开课:数据基础知识”活动,了解有关云环境和数据服务中核心数据库概念的基础知识。通过本次免费的介绍性活动,你将提升在关系数据、非关系数据、大数据和分析方面的技能。 活动时间:01 月 07 日…

SQL-leetcode-183. 从不订购的客户

183. 从不订购的客户 Customers 表: -------------------- | Column Name | Type | -------------------- | id | int | | name | varchar | -------------------- 在 SQL 中,id 是该表的主键。 该表的每一行都表示客户的 ID 和名称。 Orders 表&#…

HTML5滑块(Slider)

HTML5 的滑块&#xff08;Slider&#xff09;控件允许用户通过拖动滑块来选择数值。以下是如何实现一个简单的滑块组件的详细说明。 HTML5 滑块组件 1. 基本结构 使用 <input type"range"> 元素可以创建一个滑块。下面是基本实现的代码示例&#xff1a; <…

报错:websocket注入为null,已解决!

错误截图 原因分析&#xff1a; WebSocket 在 Spring 框架中的注入问题是由其生命周期与 Spring 容器的作用域不一致引起的。spring管理的都是单例&#xff08;singleton&#xff09;&#xff0c;和 websocket &#xff08;多对象&#xff09;相冲突。如果你的WebSocket 处理类…

ClickHouse副本搭建

一. 副本概述 副本的目的主要是保障数据的高可用性&#xff0c;ClickHouse中的副本没有主从之分。所有的副本都是平等的。 副本写入流程&#xff1a; 二. 副本搭建 1. 实验环境 hadoop1(192.168.47.128) hadoop2(192.168.47.129)2. 修改配置文件 修改两台主机/etc/click…

ChatBI来啦!NBAI 正式上线 NL2SQL 功能

NebulaAI 现已正式上线 NL2SQL 功能&#xff0c;免费开放使用&#xff01; 什么是 NL2SQL&#xff1f;NL2SQL 即通过自然语言交互&#xff0c;用户可以轻松查询、分析和管理数据库中的数据&#xff08;ChatBI&#xff09;&#xff0c;从此摆脱传统复杂的数据库操作。 欢迎免费…

科技云报到:洞见2025年科技潮流,技术大融合开启“智算时代”

科技云报到原创。 随着2024年逐渐接近尾声&#xff0c;人们不禁开始展望即将到来的2025年。这一年&#xff0c;被众多科技界人士视为开启新纪元的关键节点。站在新的起点上&#xff0c;我们将亲眼目睹未来科技如何改变我们的世界。从人工智能到量子计算&#xff0c;从基因编辑…

【数据仓库】spark大数据处理框架

文章目录 概述架构spark 架构角色下载安装启动pyspark启动spark-sehll启动spark-sqlspark-submit经验 概述 Spark是一个性能优异的集群计算框架&#xff0c;广泛应用于大数据领域。类似Hadoop&#xff0c;但对Hadoop做了优化&#xff0c;计算任务的中间结果可以存储在内存中&a…

标准库以及HAL库——按键控制LED灯代码

按键控制LED本质还是控制GPIO,和点亮一个LED灯没什么区别 点亮一个LED灯&#xff1a;是直接控制输出引脚&#xff0c;GPIO初始化推挽输出即可 按键控制LED&#xff1a;是按键输入信号从而控制输出引脚&#xff0c;GPIO初始化推挽输出一个引脚以外还得加一个GPIO上拉输入 但是…

Rabbitmq追问2

分析rabbitmq 默认使用姿势是什么 direct fanout还是什么 public void convertAndSend(String exchange, String routingKey, Object object, CorrelationData correlationData) throws AmqpException { this.send(exchange, routingKey, this.convertMessageIfNecessary(obje…

vue+js+Java在分页的el-table里实现上移、下移;置顶

这里写目录标题 一、上移、下移二、置顶 一、上移、下移 实现&#xff1a;上移到第一行后不能再上移&#xff0c;下移到最后一行不能下移&#xff0c;以及分页后能上移到前一页&#xff0c;下移能移到后一页&#xff1b;&#xff08;新增sort排序字段&#xff09; <el-tabl…