【系统设计】指标监控和告警系统

在本文中,我们将探讨如何设计一个可扩展的指标监控和告警系统。一个好的监控和告警系统,对基础设施的可观察性,高可用性,可靠性方面发挥着关键作用。

下图显示了市面上一些流行的指标监控和告警服务。

bb4f4037423fe26d6482c4a193f971e6.png

接下来,我们会设计一个类似的服务,可以供大公司内部使用。

设计要求

从一个小明去面试的故事开始。

31e4827650533fe866d41f1062af0aba.png

面试官:如果让你设计一个指标监控和告警系统,你会怎么做?

小明:好的,这个系统是为公司内部使用的,还是设计像 Datadog 这种 SaaS 服务?

面试官:很好的问题,目前这个系统只是公司内部使用。

小明:我们想收集哪些指标信息?

面试官:包括操作系统的指标信息,中间件的指标,以及运行的应用服务的 qps 这些指标。

小明:我们用这个系统监控的基础设施的规模是多大的?

面试官:1亿日活跃用户,1000个服务器池,每个池 100 台机器。

小明:指标数据要保存多长时间呢?

面试官:我们想保留一年。

小明:好吧,为了较长时间的存储,可以降低指标数据的分辨率吗?

面试官:很好的问题,对于最新的数据,会保存 7 天,7天之后可以降低到1分钟的分辨率,而到 30 天之后,可以按照 1 小时的分辨率做进一步的汇总。

小明:支持的告警渠道有哪些?

面试官:邮件,电 钉钉,企业微信,Http Endpoint。

小明:我们需要收集日志吗?还有是否需要支持分布式系统的链路追踪?

面试官:目前专注于指标,其他的暂时不考虑。

小明:好的,大概都了解了。

总结一下,被监控的基础设施是大规模的,以及需要支持各种维度的指标。另外,整体的系统也有较高的要求,要考虑到可扩展性,低延迟,可靠性和灵活性。

基础知识

一个指标监控和告警系统通常包含五个组件,如下图所示

9b763ab81d7b17895872366dc7711fc3.png
  1. 1. 数据收集:从不同的数据源收集指标数据。

  2. 2. 数据传输:把指标数据发送到指标监控系统。

  3. 3. 数据存储:存储指标数据。

  4. 4. 告警:分析接收到的数据,检测到异常时可以发出告警通知。

  5. 5. 可视化:可视化页面,以图形,图表的形式呈现数据。

数据模式

指标数据通常会保存为一个时间序列,其中包含一组值及其相关的时间戳。

序列本身可以通过名称进行唯一标识,也可以通过一组标签进行标识。

让我们看两个例子。

示例1:生产服务器 i631 在 20:00 的 CPU 负载是多少?

ab45a258f507d7fa706bf75f424e5afe.png

上图标记的数据点可以用下面的格式表示

99d69353443d4a6a774c2fa0d34c6b4d.png

在上面的示例中,时间序列由指标名称,标签(host:i631,env:prod),时间戳以及对应的值构成。

示例2:过去 10 分钟内上海地区所有 Web 服务器的平均 CPU 负载是多少?

从概念上来讲,我们会查询出和下面类似的内容

CPU.load host=webserver01,region=shanghai 1613707265 50CPU.load host=webserver01,region=shanghai 1613707270 62CPU.load host=webserver02,region=shanghai 1613707275 43

我们可以通过上面每行末尾的值计算平均 CPU 负载,上面的数据格式也称为行协议。是市面上很多监控软件比较常用的输入格式,Prometheus 和 OpenTSDB 就是两个例子。

每个时间序列都包含以下内容:

  • • 指标名称,字符串类型的 metric name 。

  • • 一个键值对的数组,表示指标的标签,List<key,value>

  • • 一个包含时间戳和对应值的的数组,List <value, timestamp>

数据存储

数据存储是设计的核心部分,不建议构建自己的存储系统,也不建议使用常规的存储系统(比如 MySQL)来完成这项工作。

理论下,常规数据库可以支持时间序列数据, 但是需要数据库专家级别的调优后,才能满足数据量比较大的场景需求。

具体点说,关系型数据库没有对时间序列数据进行优化,有以下几点原因

  • • 在滚动时间窗口中计算平均值,需要编写复杂且难以阅读的 SQL。

  • • 为了支持标签(tag/label)数据,我们需要给每个标签加一个索引。

  • • 相比之下,关系型数据库在持续的高并发写入操作时表现不佳。

那 NoSQL 怎么样呢?理论上,市面上的少数 NoSQL 数据库可以有效地处理时间序列数据。比如 Cassandra 和 Bigtable 都可以。但是,想要满足高效存储和查询数据的需求,以及构建可扩展的系统,需要深入了解每个 NoSQL 的内部工作原理。

相比之下,专门对时间序列数据优化的时序数据库,更适合这种场景。

OpenTSDB 是一个分布式时序数据库,但由于它基于 Hadoop 和 HBase,运行 Hadoop/HBase 集群也会带来复杂性。Twitter 使用了 MetricsDB 时序数据库存储指标数据,而亚马逊提供了 Timestream 时序数据库服务。

根据 DB-engines 的报告,两个最流行的时序数据库是 InfluxDB 和 Prometheus ,它们可以存储大量时序数据,并支持快速地对这些数据进行实时分析。

如下图所示,8 核 CPU 和 32 GB RAM 的 InfluxDB 每秒可以处理超过 250,000 次写入。

2ddefcd193f14bc0b5439bcdb73bc342.png

高层次设计

a5d00a87a0743f8cfda4e58ac31f06fa.png
  • • Metrics Source 指标来源,应用服务,数据库,消息队列等。

  • • Metrics Collector 指标收集器。

  • • Time series DB 时序数据库,存储指标数据。

  • • Query Service 查询服务,向外提供指标查询接口。

  • • Alerting System 告警系统,检测到异常时,发送告警通知。

  • • Visualization System 可视化,以图表的形式展示指标。

深入设计

7a0000ca02d33ba87c9bb33ee278b029.png

现在,让我们聚焦于数据收集流程。主要有推和拉两种方式。

拉模式

5e8645b9483dbb98324fad1906587ee2.png

上图显示了使用了拉模式的数据收集,单独设置了数据收集器,定期从运行的应用中拉取指标数据。

这里有一个问题,数据收集器如何知道每个数据源的地址? 一个比较好的方案是引入服务注册发现组件,比如 etcd,ZooKeeper,如下

0ac3be8c8f222f77e846e57578895008.png

下图展示了我们现在的数据拉取流程。

585f3a93d43a73cb5eb13690fd5a4439.png
  1. 1. 指标收集器从服务发现组件中获取元数据,包括拉取间隔,IP 地址,超时,重试参数等。

  2. 2. 指标收集器通过设定的 HTTP 端点获取指标数据。

在数据量比较大的场景下,单个指标收集器是独木难支的,我们必须使用一组指标收集器。但是多个收集器和多个数据源之间应该如何协调,才能正常工作不发生冲突呢?

一致性哈希很适合这种场景,我们可以把数据源映射到哈希环上,如下

d83a9b4c5166fb08fbabfb9d46b9933b.png

这样可以保证每个指标收集器都有对应的数据源,相互工作且不会发生冲突。

推模式

如下图所示,在推模式中,各种指标数据源(Web 应用,数据库,消息队列)直接发送到指标收集器。

a1723433c7f60f68d16ce10ed1bab3f2.png

在推模式中,需要在每个被监控的服务器上安装收集器代理,它可以收集服务器的指标数据,然后定期的发送给指标收集器。

推和拉两种模式哪种更好?没有固定的答案,这两个方案都是可行的,甚至在一些复杂场景中,需要同时支持推和拉。

扩展数据传输

edee94416a7e8b1b53835fdb708659ce.png

现在,让我们主要关注指标收集器和时序数据库。不管使用推还是拉模式,在需要接收大量数据的场景下,指标收集器通常是一个服务集群。

但是,当时序数据库不可用时,就会存在数据丢失的风险,所以,我们引入了 Kafka 消息队列组件, 如下图

394b05f39561161c0b852dddfb852b12.png

指标收集器把指标数据发送到 Kafka 消息队列,然后消费者或者流处理服务进行数据处理,比如 Apache Storm、Flink 和 Spark, 最后再推送到时序数据库。

指标计算

指标在多个地方都可以聚合计算,看看它们都有什么不一样。

  • • 客户端代理:客户端安装的收集代理只支持简单的聚合逻辑。

  • • 传输管道:在数据写入时序数据库之前,我们可以用 Flink 流处理服务进行聚合计算,然后只写入汇总后的数据,这样写入量会大大减少。但是由于我们没有存储原始数据,所以丢失了数据精度。

  • • 查询端:我们可以在查询端对原始数据进行实时聚合查询,但是这样方式查询效率不太高。

时序数据库查询语言

大多数流行的指标监控系统,比如 Prometheus 和 InfluxDB 都不使用 SQL,而是有自己的查询语言。一个主要原因是很难通过 SQL 来查询时序数据, 并且难以阅读,比如下面的SQL 你能看出来在查询什么数据吗?

select id,temp,avg(temp) over (partition by group_nr order by time_read) as rolling_avg
from (select id,temp,time_read,interval_group,id - row_number() over (partition by interval_group order by time_read) as group_nrfrom (select id,time_read,"epoch"::timestamp + "900 seconds"::interval * (extract(epoch from time_read)::int4 / 900) as interval_group,tempfrom readings) t1
) t2
order by time_read;

相比之下, InfluxDB 使用的针对于时序数据的 Flux 查询语言会更简单更好理解,如下

from(db:"telegraf")|> range(start:-1h)|> filter(fn: (r) => r._measurement == "foo")|> exponentialMovingAverage(size:-10s)

数据编码和压缩

数据编码和压缩可以很大程度上减小数据的大小,特别是在时序数据库中,下面是一个简单的例子。

f701fd073cf9c6abd99bca40ab156640.png

因为一般数据收集的时间间隔是固定的,所以我们可以把一个基础值和增量一起存储,比如 1610087371, 10, 10, 9, 11 这样,可以占用更少的空间。

下采样

下采样是把高分辨率的数据转换为低分辨率的过程,这样可以减少磁盘使用。由于我们的数据保留期是1年,我们可以对旧数据进行下采样,这是一个例子:

  • • 7天数据,不进行采样。

  • • 30天数据,下采样到1分钟的分辨率

  • • 1年数据,下采样到1小时的分辨率。

我们看另外一个具体的例子,它把 10 秒分辨率的数据聚合为 30 秒分辨率。

原始数据

9d47fd102c5a27e5a74cca72432d6412.png

下采样之后

686932ed252f9bbecf92e1d3ad8d8a4e.png

告警服务

让我们看看告警服务的设计图,以及工作流程。

1baa4b38dd4c054548b234bb1890e499.png
  1. 1. 加载 YAML 格式的告警配置文件到缓存。

  2. - name: instance_down
      rules:
      # 服务不可用时间超过 5 分钟触发告警.
      - alert: instance_down
        expr: up == 0
        for: 5m
        labels:
          severity: page

  3. 2. 警报管理器从缓存中读取配置。

  4. 3. 根据告警规则,按照设定的时间和条件查询指标,如果超过阈值,则触发告警。

  5. 4. Alert Store 保存着所有告警的状态(挂起,触发,已解决)。

  6. 5. 符合条件的告警会添加到 Kafka 中。

  7. 6. 消费队列,根据告警规则,发送警报信息到不同的通知渠道。

可视化

可视化建立在数据层之上,指标数据可以在指标仪表板上显示,告警信息可以在告警仪表板上显示。下图显示了一些指标,服务器的请求数量、内存/CPU 利用率、页面加载时间、流量和登录信息。

e6a1512518056543c1b616be48b62d2d.png

Grafana 可以是一个非常好的可视化系统,我们可以直接拿来使用。

总结

在本文中,我们介绍了指标监控和告警系统的设计。在高层次上,我们讨论了数据收集、时序数据库、告警和可视化,下图是我们最终的设计:

79bddc191232bf2a1ded78e00ded0471.png

Reference

[0] System Design Interview Volume 2: https://www.amazon.com/System-Design-Interview-Insiders-Guide/dp/1736049119

[1] Datadog: https://www.datadoghq.com/

[2] Splunk: https://www.splunk.com/

[3] Elastic stack: https://www.elastic.co/elastic-stack

[4] Dapper, a Large-Scale Distributed Systems Tracing Infrastructure: https://research.google/pubs/pub36356/

[5] Distributed Systems Tracing with Zipkin: https://blog.twitter.com/engineering/en_us/a/2012/distributed-systems-tracing-with-zipkin.html

[6] Prometheus: https://prometheus.io/docs/introduction/overview/

[7] OpenTSDB - A Distributed, Scalable Monitoring System: http://opentsdb.net/

[8] Data model: : https://prometheus.io/docs/concepts/data_model/

[9] Schema design for time-series data | Cloud Bigtable Documentation https://cloud.google.com/bigtable/docs/schema-design-time-series

[10] MetricsDB: TimeSeries Database for storing metrics at Twitter: https://blog.twitter.com/engineering/en_us/topics/infrastructure/2019/metricsdb.html

[11] Amazon Timestream: https://aws.amazon.com/timestream/

[12] DB-Engines Ranking of time-series DBMS: https://db-engines.com/en/ranking/time+series+dbms

[13] InfluxDB: https://www.influxdata.com/

[14] etcd: https://etcd.io

[15] Service Discovery with Zookeeper https://cloud.spring.io/spring-cloud-zookeeper/1.2.x/multi/multi_spring-cloud-zookeeper-discovery.html

[16] Amazon CloudWatch: https://aws.amazon.com/cloudwatch/

[17] Graphite: https://graphiteapp.org/

[18] Push vs Pull: http://bit.ly/3aJEPxE

[19] Pull doesn’t scale - or does it?: https://prometheus.io/blog/2016/07/23/pull-does-not-scale-or-does-it/

[20] Monitoring Architecture: https://developer.lightbend.com/guides/monitoring-at-scale/monitoring-architecture/architecture.html

[21] Push vs Pull in Monitoring Systems: https://giedrius.blog/2019/05/11/push-vs-pull-in-monitoring-systems/

[22] Pushgateway: https://github.com/prometheus/pushgateway

[23] Building Applications with Serverless Architectures https://aws.amazon.com/lambda/serverless-architectures-learn-more/

[24] Gorilla: A Fast, Scalable, In-Memory Time Series Database: http://www.vldb.org/pvldb/vol8/p1816-teller.pdf

[25] Why We’re Building Flux, a New Data Scripting and Query Language: https://www.influxdata.com/blog/why-were-building-flux-a-new-data-scripting-and-query-language/

[26] InfluxDB storage engine: https://docs.influxdata.com/influxdb/v2.0/reference/internals/storage-engine/

[27] YAML: https://en.wikipedia.org/wiki/YAML

[28] Grafana Demo: https://play.grafana.org/

END

做了一个 .NET 的学习网站,内容涵盖了分布式系统,数据结构与算法,设计模式,操作系统,计算机网络等,以及工作推荐和面试经验分享,欢迎来撩。

回复 dotnet 获取网站地址。

回复 面试题 获取 .NET 面试题。

回复 程序员副业 获取适合程序员的副业指南。

3b0249e834fc3d11fa794c43c38e9430.gif

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言试题154之两个字符串连接程序

📃个人主页:个人主页 🔥系列专栏:C语言试题200例 💬推荐一款模拟面试、刷题神器👉 点击跳转进入网站 ✅作者简介:大家好,我是码莎拉蒂,CSDN博客专家(全站排名Top 50),阿里云博客专家、51CTO博客专家、华为云享专家 1、题目 题目:两个字符串连接程序 2 、温馨…

[转]Android studio 快速解决Gradle's dependency cache may be corrupt 和 Gradle配置 gradle

用了好久的AS了&#xff0c;官方版本更新&#xff0c;各种配置工具 也跟着更新。更新后导入工程时&#xff08;使用Android工程编译或者导入新的工程没有对应的gradle版本&#xff09;一些电脑出现一下问题。 Error:Failed to open zip file. Gradles dependency cache may …

mybatis源码学习

2019独角兽企业重金招聘Python工程师标准>>> 学习主线&#xff1a; 目的&#xff1a;mybatis的作用orm框架&#xff0c;用了该框架就不用自己调用jdbc了。 用法&#xff1a;。。。。。 逻辑&#xff1a;。。。。。 源代码&#xff1a;。。。。。 1、猜想mybatis对数…

自己封装一个弹框插件

弹出层提示信息&#xff0c;这是移动前端开发中最常见的需求&#xff0c;你可能会想到一些流行的弹框插件&#xff0c;比如 经典的artDialog 炫酷的Sweetalert等等.. 但是慢慢地你其实会发现通常情况下需求定制化要求较高&#xff0c;一般的弹框插件可能只满足大部分要求&#…

.NET MAUI 性能提升

点击蓝字关注我们作者&#xff1a;Jonathan Peppers翻译&#xff1a;Yijing Sun校稿&#xff1a;Amy Peng排版&#xff1a;Rani Sun精彩预告*本文干货满满&#xff0c;预计阅读时间32分钟&#xff0c;建议收藏保存。.NET多平台应用程序UI (MAUI)将android、iOS、macOS和Windows…

C语言试题155之有五个学生,每个学生有 3 门课的成绩,从键盘输入以上数据(包括学生号,姓名,三门课成绩),计算出 平均成绩,况原有的数据和计算出的平均分数存放在磁盘文件“stud“中

📃个人主页:个人主页 🔥系列专栏:C语言试题200例 💬推荐一款模拟面试、刷题神器👉 点击跳转进入网站 ✅作者简介:大家好,我是码莎拉蒂,CSDN博客专家(全站排名Top 50),阿里云博客专家、51CTO博客专家、华为云享专家 1、题目 题目:有五个学生,每个学生有 3 门…

仿照支付宝账单界面--listview分组显示 用来做!发!财树充值交易明细

QQ图片20150430155638.png (151.65 KB, 下载次数: 32) 下载链接: http://pan.baidu.com/s/1kVMY1SV 密码: i8ta

C语言试题156之有两个磁盘文件 A 和 B,各存放一行字母,要求把这两个文件中的信息合并(按字母顺序排列), 输出到一个新文件 C 中。

📃个人主页:个人主页 🔥系列专栏:C语言试题200例 💬推荐一款模拟面试、刷题神器👉 点击跳转进入网站 ✅作者简介:大家好,我是码莎拉蒂,CSDN博客专家(全站排名Top 50),阿里云博客专家、51CTO博客专家、华为云享专家 1、题目 题目:有两个磁盘文件 A 和 B,各存…

【ArcGIS微课1000例】0002:创建渔网(Create fishnet)

本文讲解ArcGIS软件中渔网(fishnet)工具的原理,方法及使用技巧。 文章目录 微课目标工具介绍实现过程微课目标 如下图所示,影像为无人机航测生产的DOM,现在需要在ArcGIS平台中进行DLG数据采集(数字化),由于测区较大,需要创建500*500的渔网,并对影像进行裁剪下发给多…

使用 Scrutor 快速实现“装饰者模式”

装饰者模式介绍装饰器模式&#xff08;Decorator Pattern&#xff09;是在不改变原类和使用继承的情况下&#xff0c;动态地给一个对象添加一些额外的职责。它是通过创建一个包装对象&#xff0c;也就是装饰来包裹真实的对象。可以在如下使用场景中使用装饰器模式&#xff1a;在…

C语言试题157之从键盘输入一个字符串,将小写字母全部转换成大写字母,然后输出到一个磁盘文件“test”中保存。 输入的字符串以!结束

📃个人主页:个人主页 🔥系列专栏:C语言试题200例 💬推荐一款模拟面试、刷题神器👉 点击跳转进入网站 ✅作者简介:大家好,我是码莎拉蒂,CSDN博客专家(全站排名Top 50),阿里云博客专家、51CTO博客专家、华为云享专家 1、题目 题目:从键盘输入一个字符串,将小…

【ArcGIS微课1000例】0001:添加XY数据(Add XY data)生成shp

用过CASS的人都知道&#xff0c;野外数字测图得到的点数据&#xff08;平面坐标&#xff09;可以直接在CASS中展点&#xff0c;进一步绘制地形图。那么&#xff0c;带有坐标的数据能不能在ArcGIS中实现点图层的生成呢&#xff1f;答案是必须的&#xff01; 本文以气象台站Excel…

算法导论--广度优先搜索和深度优先搜索

广度优先搜索 在给定图G(V,E)和一个特定的源顶点s的情况下&#xff0c;广度优先搜索系统地探索G中的边&#xff0c;以期“发现”可从s 到达的所有顶点&#xff0c;并计算s 到所有这些可达顶点之间的距离&#xff08;即最少的边数&#xff09;。该搜索算法同时还能生成一棵根为s…

动手学 docker

背景动手学 docker最近&#xff0c;终于完成了 动手学 docker 系列的编写。动手学 docker 是 动手学系列 的首个系列。如果反馈的效果不错&#xff0c;后续还将推出 动手学 devops动手学 kubernetes动手学 istio 等系列。动手学系列 的构思来源于 李沐 老师的 动手学深度学习 。…

Linux零基础入学之1-1课程介绍了解RHEL7安装RHEL7

【本节内容】* 课程介绍* RHEL7了解* RHEL7.2的安装* 实战&#xff1a;组装服务器【Linux介绍】服务器种类&#xff1a;刀片式、塔式&#xff08;机架式&#xff09;1U&#xff1a;4.45cm 三指宽 指服务器的高度贝尔实验室 Unix 肯汤普森 & 丹尼斯里奇二人合作用…

[转]Android 常见安全漏洞修复理论与实践

前言 前段时间公司对应用在爱加密上进行了安全扫描&#xff0c;本文将基于爱加密的漏洞分析报告&#xff0c;针对部分内容&#xff0c;介绍理论修复实践 最小化特权准则概念介绍 最小化特权准则&#xff0c;即指组件只能供自身应用调用&#xff0c;尽可能禁止其他应用访问及…

C语言试题158之从键盘输入一些字符,逐个把它们送到磁盘上去,直到输入一个#为止。

📃个人主页:个人主页 🔥系列专栏:C语言试题200例 💬推荐一款模拟面试、刷题神器👉 点击跳转进入网站 ✅作者简介:大家好,我是码莎拉蒂,CSDN博客专家(全站排名Top 50),阿里云博客专家、51CTO博客专家、华为云享专家 1、题目 题目:从键盘输入一些字符,逐个把…

我是怎么自学 Git / GitHub 的?

大家好我是鱼皮&#xff0c;Git 和 GitHub 是如今团队协作开发必不可少的技能&#xff0c;且不说程序员&#xff0c;就连很多产品也在学习它们。今天分享一下我自学 Git 和 GitHub 的经验&#xff0c;希望起到一个 导学 的作用&#xff0c;帮助大家抓住重点&#xff0c;节省时间…

【ArcGIS微课1000例】0004:值提取至点(Extract value to point)

文章目录 问题描述值提取至点工具介绍案例实现过程注意事项问题描述 研究区分布有成千上万个离散的矢量点(根据范围创建随机点),但是点上没有高程值,研究区DEM是有的,那么怎样在ArcGIS中提取每个点对应的高程值? 离散点分布情况: DEM数据(ArcGlobe中三维显示):

C语言试题159之计算字符串中子串出现的次数

📃个人主页:个人主页 🔥系列专栏:C语言试题200例 💬推荐一款模拟面试、刷题神器👉 点击跳转进入网站 ✅作者简介:大家好,我是码莎拉蒂,CSDN博客专家(全站排名Top 50),阿里云博客专家、51CTO博客专家、华为云享专家 1、题目 题目:两个字符串连接程序 2 、温馨…