运维监控专项学习笔记-id:0-需求场景、监控作用、监控能力

参考来源:

极客时间专栏-运维监控系统实战笔记,作者:秦晓辉

一、需求场景

学习监控知识,得先了解为什么,也就是监控是因何产生的,解决了什么问题,有哪些典型的方案,分别有什么优缺点。

1.1监控系统诉求

最初始的需求,其实就是一句话:系统出问题了我们能及时感知到

随着时代的发展,

我们对监控系统提出了更多的诉求,比如:

通过监控了解数据趋势,知道系统在未来的某个时刻可能出问题,预知问题。

通过监控了解系统的水位情况,为服务扩缩容提供数据支撑。

通过监控来给系统把脉,感知到哪里需要优化,比如一些中间件参数的调优。

通过监控来洞察业务,提供业务决策的数据依据,及时感知业务异常。

1.2监控相关的问题

指标有哪些类型,哪类指标比较关键?

如何部署一套高可用的监控系统,存储应该如何选型?

如何监控 MySQL、Redis、Kafka、ElasticSearch?

如何监控 Kubernetes 这么复杂的平台?

如何埋点,如何分析日志?

如何做到事件闭环和告警自愈?

......

1.3学习监控知识的人员画像

每个关注高可用、关注服务稳定性的技术人员 都应该学习监控相关的知识。

在稳定性保障体系中,核心就是在干一件事,减少故障。

故障的生命周期 (三个相关指标:MTBF、MTTR、MTTF,两者之间B、修复R、失效F)

减少故障 有两个层面的意思,一个是做好常态预防,不让故障发生;另一个是如果故障发生,要能尽快止损,减少故障时长。而监控的典型作用,就是帮助我们发现及定位故障,这两个环节对于减少故障时长至关重要。

1.4 监控的作用:减少故障

监控的作用还有很多,比如用于日常巡检,作为性能调优的数据佐证,提前发现一些设备、中间件不合理的配置。之所以能做到这些,是因为所有优秀的软件,都内置了监控数据的暴露方法,让用户可以对其进行观测,了解其健康状况。可被监控和观测,也是我们开发软件

时必须考虑的一环。

二、可观测性三大支柱和代表产品:指标监控、日志监控、链路监控

2.1 指标监控

我们所说的监控系统,其实只是指标监控,通常使用折线图形态呈现在图表上,比如某个机器的 CPU 利用率、某个数据库实例的流量或者网站的在线人数,都可以体现为随着时间而变化的趋势图。

指标监控只能处理数字,但它的历史数据存储成本较低,实时性好,生态庞大,是可观测性领域里最重要的一根支柱。聚焦在指标监控领域的开源产品有 Zabbix、Open-Falcon、Prometheus、Nightingale 等。

2.2 日志监控

除了指标监控,另一个重要的可观测性支柱是日志。从日志中可以得到很多信息,对于了解软件的运行情况、业务的运营情况都很关键。比如操作系统的日志、接入层的日志、服务运行日志,都是重要的数据源。

从操作系统的日志中,可以得知很多系统级事件的发生;从接入层的日志中,可以得知有哪些域名、IP、URL 收到了访问,是否成功以及延迟情况等;从服务日志中可以查到 Exception的信息,调用堆栈等,对于排查问题来说非常关键。但是日志数据通常量比较大,不够结构化,存储成本较高。

处理日志这个场景,也有很多专门的系统,比如开源产品 ELK 和 Loki,商业产品 Splunk 和Datadog。

2.3 链路监控

可观测性最后一大支柱是链路追踪。随着微服务的普及,原本的单体应用被拆分成很多个小的服务,服务之间有错综复杂的调用关系,一个问题具体是哪个模块导致的,排查起来其实非常困难。

链路追踪的思路是以请求串联上下游模块,为每个请求生成一个随机字符串作为请求 ID。服务之间互相调用的时候,把这个 ID 逐层往下传递,每层分别耗费了多长时间,是否正常处理,都可以收集起来附到这个请求 ID 上。后面追查问题时,拿着请求 ID 就可以把串联的所

有信息提取出来。链路追踪这个领域也有很多产品,比如 Skywalking、Jaeger、Zipkin等,都是个中翘楚。

三、指标监控的解决方案

对指标监控领域的多个开源解决方案做了横评对比,帮助你做技术方案的选型

四、监控核心能力-监控、告警

4.1我们常说的监控指的是啥

监控系统就是围绕指标的采集、传输、存储、分析、可视化的一个系统。

监控:这个词在不同的上下文会有不同的语义,有的时候表示数据采集和可视化,有的时候表示整个监控系统。不过不管怎么理解,通常都不影响交流

4.2监控能力的关键概念1:监控指标

监控指标-三种典型方式和代表产品

监控指标是指数值类型的监控数据,比如某个机器的内存利用率,某个 MySQL 实例的当前连接数,某个 Redis 的最大内存上限等等。不同的监控系统,对于监控指标有不同的描述方式,

典型的方式有三种:

复制代码
1.监控指标:全局的唯一字符串方式-graphite

监控指标通常是一个全局唯一的字符串,比如某机器的内存利用率host.10.2.3.4.mem_used_percent,这个字符串中包含了机器的信息,也包含了指标名,可以唯一标识一条监控指标。 //命名的艺术dog.jpg

相对老一些的监控系统,比如 Graphite,就是使用这种方式来标识监控指标的。一些老的监控数据采集器,比如 Collectd,也是这样标识监控指标的。

虽然这种方式一目了然,非常清晰,但是缺少对维度信息的描述,不便于做聚合计算

举例帮助理解

myhost 这个机器上部署了两个服务,分别是 service1 和 service2。有些请求状态码是

200,有些是 500,有些 HTTP method 是 get,有些是 post。我们想分别统计这些指标的

数量,就要把这些分类维度信息都拼到指标标识中。但是这样做会产生两个弊端:一是看起来
比较混乱,二是不方便聚合统计。

举个例子,比如我想计算 service1 这个服务的成功率 ,要把 service1 里所有状态码为 200

的请求数量拿到,除以 service1 所有请求的数量。如果预先知道所有状态码、所有 HTTP

method,则可以枚举指标名称,拉取监控数据。如果不知道所有状态码和 HTTP method,

就要先用正则匹配指标标识,查询出指标列表再拉取监控数据做计算,处理起来非常麻烦。

bash 复制代码
myhost.service1.http_request.200.get
myhost.service1.http_request.200.post
myhost.service1.http_request.500.get
myhost.service1.http_request.500.post
myhost.service2.http_request.200.get
myhost.service2.http_request.500.post

其实我这是用马后炮视角解释这个问题的,实际上,在 Graphite、Collectd、Zabbix、Cacti这些软件盛行的时代,这个问题并不明显。因为那个时代主要关注的是机器设备、数据库、中间件的监控,不会有很多维度的信息。直到业界开始关注应用层面监控的时候,才暴露出这个问题

2.监控指标:标签集的组合作为指标标识-OpenTSDB

2010 年左右,有一款名叫 OpenTSDB 的时序数据库诞生了。虽然现在已经较少使用了,但是 OpenTSDB 描述指标的方式,对业界有很大影响。下面是通过文本协议推给OpenTSDB 的数据示例,我们可以从中看出指标标识的定义方式

bash 复制代码
mysql.bytes_received 1287333217 327810227706 schema=foo host=db1
mysql.bytes_sent 1287333217 6604859181710 schema=foo host=db1
mysql.bytes_received 1287333232 327812421706 schema=foo host=db1
mysql.bytes_sent 1287333232 6604901075387 schema=foo host=db1
mysql.bytes_received 1287333321 340899533915 schema=foo host=db2
mysql.bytes_sent 1287333321 5506469130707 schema=foo host=db2

上面这 6 条监控指标,都通过空格把指标分隔成了多个字段。第一段是指标名,第二段是时间戳(单位是秒),第三段是指标值,剩下的部分是多个标签(tags/labels),每个标签都是 key=value 的格式,多个标签之间使用空格分隔。

除了 OpenTSDB,新时代的时序库大都引入了标签的概念,比如 Prometheus,它们甚至认为指标名也是一种特殊的标签(其标签 key 是 name ),所以 Prometheus 仅仅使用标签集作为指标标识,从 Prometheus 的数据结构定义中就可以看出来。

3.监控指标:优雅高效的 Influx 指标格式

InfluxData 公司有一款开源时序库非常有名,叫InfluxDB,InfluxDB 在接收监控数据写入

时,设计了一个非常精巧的指标格式,一行可以传输多个指标。

bash 复制代码
mesurement,labelkey1=labelval1,labelkey2=labelval2 field1=1.2,field2=2.3 timestam

总体来看,分为 4 个部分,measurement,tag_set field_set timestamp,其中 tag_set 是可选的,tag_set 与前面的 measurement 之间用逗号分隔,其他各个部分之间都是用空格来分隔的。我们可以通过下面的例子来理解。

bash 复制代码
weather,location=us-midwest temperature=82 1465839830100400200
| -------------------- -------------- |
| | | |
| | | |
+-----------+--------+-+---------+-+---------+
|measurement|,tag_set| |field_set| |timestamp|
+-----------+--------+-+---------+-+---------+

我们把上面 OpenTSDB 的指标示例改写成 Influx 格式,结果是这样的。

bash 复制代码
mysql,schema=foo,host=db1 bytes_received=327810227706,bytes_sent=6604859181710 12
mysql,schema=foo,host=db1 bytes_received=327812421706,bytes_sent=6604901075387 12
mysql,schema=foo,host=db2 bytes_received=340899533915,bytes_sent=5506469130707 12

注意,时间戳的单位是纳秒。这种写法设计很精巧,标签重复度低,field 越多的情况下它的优势越明显,网络传输的时候可以节省更多带宽。当然了,OpenTSDB 的格式或者Prometheus 的格式如果做了数据压缩,节省带宽的效果也是不错的,因为字符的压缩效果一

般比较明显。现如今机房内部通信动辄万兆网卡,这个流量的大小区别倒也不用太关注。

三类监控指标的优缺点对比

4.3监控能力的关键概念2:指标数据类型

##指标数据类型来源

有些监控系统是不区分指标类型的,有些会做区分。90 年代左右社区就出现了一款作品RRDtool,它是一个环形数据库,也是一个绘图引擎,很多监控工具都是使用 RRDtool 来存储或绘制监控趋势图的,比如 Cacti、MRTG、Zabbix 等等。RRDtool 还提出了数据类型的概念,支持 GAUGE、COUNTER、DERIVE、DCOUNTER、DDERIVE、ABSOLUTE 等多种数据类型。

四种常见监控数据类型的介绍

Prometheus 生态也支持数据类型,分为 Gauge、Counter、Histogram、Summary4 种,

下面我们简单了解一下 Prometheus 的这 4 种类型。

  1. Gauge
    测量值类型,可大可小,可正可负。这种类型的数据,我们通常关注的是当前值,比如房间里的人数、队列积压的消息数、今年公司的收入和净利润。

2.Counter

表示单调递增的值,比如操作系统自启动以来网卡接收到的所有流量包的数量。每接收到一个包,操作系统就会加 1,所以这个值是持续递增的。但是操作系统可能会重启,导致这个值出现重置,比如第一次是从 0 一直涨到了 239423423,然后机器重启,新采集的数据是一些比239423423 小很多的值,这种情况怎么办?此时 Prometheus 看到值没有递增,就能感知到重置的情况,会把新采集的值加上 239423423 再做计算。

3.Histogram

直方图类型,用于描述数据分布,最典型的应用场景就是监控延迟数据,计算 90 分位、99分位的值。所谓的分位值,就是把一批数据从小到大排序,然后取 X% 位置的数据,90 分位就是指样本数据第 90% 位置的值。

有些服务访问量很高,每秒几百万次,如果要把所有请求的延迟数据全部拿到,排序之后再计算分位值,这个代价就太高了。使用 Histogram 类型,可以用较小的代价计算一个大概值。
当然,不是特别准确,但是在监控场景足够用了
,监控毕竟只是一个采样的系统,对数据准确

性要求没有那么高。

Histogram 的做法是根据数据的 value 范围,规划多个桶(bucket),把样本数据点放入不同的桶来统计。比如我们有个服务 service1,它的接口延迟最小的通常在一两百毫秒,最大的通常在 1 秒,如果超过 3 秒,大概率就是系统不正常了。

虽然 Histogram 这种做法相比于把所有请求延迟数据都存储起来再计算延迟,性能有了巨大

的提升,但是要同时计算成千上万个接口的分位值延迟数据,还是非常耗费资源的 ,甚至会造

成服务端 OOM。于是就有了 Summary 类型。

  1. Summary
    Summary 这种类型是在客户端计算分位值,然后把计算之后的结果推给服务端存储,展示的时候直接查询即可,不需要做很重的计算,性能大幅提升。

听起来不错,但是有个问题,Summary 的计算是在客户端计算的,也就意味着不是全局的分位值,比如某个服务 service1,部署在两个机器上,服务代码里通过内嵌 Prometheus 的SDK 做了埋点监控,SDK 里会计算 Summary 数据。也就是说,分位值延迟数据是进程粒度的,不是整个服务粒度的。

这个问题很严重吗?其实也没什么大不了的,这两个机器前面肯定有负载均衡,负载均衡会保证把请求均匀地打给后端的两个实例。一个实例内部计算的分位值,理论上和全局计算的分位值差别不会很大。另外,如果某个实例有故障,比如硬盘问题,导致落在这个实例的请求延迟大增,我们在实例粒度计算的延迟数据反而更容易发现问题。

为什么要做监控数据分类?存储能识别数据类型吗

为什么还需要划分这么多类型呢?最主要的作用是在采集侧埋点的时候,SDK 会根据数据类型做不同的计算逻辑,比如 Histogram 类型,每次请求进来的时候,代码里调用一下 SDK的 Observe 方法通知 SDK,SDK 就会自动计算生成多个指标,提升埋点便利性。

从存储角度还真的不需要知道,存储的时候只要知道指标标识、时间戳、值,就足够了。后续做 PromQL 查询计算的时候,不同的函数有不同的行为,比如 rate、increase 函数,我们就给它传入 Counter 类型的数据作为参数即可。对于 histogram_quantile 函数,就传入

带有 le 标签的 bucket 指标。

4.4 告警能力的核心概念1:告警收敛

告警收敛 (大事不好啦~~~)

基础设施层面的故障,比如基础网络问题,可能会瞬间产生很多告警事件,形成告警风暴,导致接收告警的媒介拥塞,比如手机不停接收到短信和电话呼入,没办法使用。这个时候,我们就要想办法让告警事件变少,用的方法就是告警收敛

最典型的手段 是告警聚合发送,聚合可以采用不同的维度,比如时间维度、策略维度、监控对象维度等等。如果 100 台机器同时报失联,就可以合并成一条告警通知,减少打扰。

另外一个典型的收敛手段是把多个事件聚合成告警,把多个告警聚合成故障。比如某个机器的CPU 利用率告警,监控系统可能每分钟都会产生一条事件,这多个事件的告警规则、监控对象、监控指标都相同,所以可以收敛为一条告警。假设有 100 台机器都告警了,其中 50 台属于业务 A,另外 50 台属于业务 B,我们可以按照业务来做聚合,聚合之后产生两个故障,这样就可以起到很好的收敛效果。

4.5 告警能力的核心概念2:告警闭环

闭环这个词是个互联网黑话,表示某个事情有始有终,告警怎么判断是否闭环了呢?问题最终被解决,告警恢复,就算是闭环了 。产品怎么设计才能保证告警闭环呢?通常来讲,没人响应的告警能够升级通知,告警 oncall 人员可以认领告警,基本就有比较好的保障了。

快速回顾

监控:这个词在不同的上下文会有不同的语义,有的时候表示数据采集和可视化,有的时候表示整个监控系统。不过不管怎么理解,通常都不影响交流。

监控指标:这个概念很关键,不同的监控产品有不同的描述方式,不过随着 OpenMetrics标准的建立,指标描述方式会渐渐趋于一致。重点要了解 Prometheus 的指标描述方式metric + labels,当然 metric 也可以看作一个特殊的 label。Influx 格式也很重要,建议你掌握,如果使用 Telegraf 作为采集器,就绕不过去这个格式。

指标类型:针对时下流行的 Prometheus,我们讲解了 4 种指标类型及每个类型的适用场景,最后明确了指标类型最核心的作用:在采集侧埋点时,SDK 会根据数据类型做不同的计算逻辑。

时序库:存储时序序列数据的数据库,它已经成为了一个单独的数据库细分方向,而且随着IoT 的场景越来越多,以及微服务的发展,时序库这个话题也越来越流行。

告警收敛和告警闭环:告警事件层面的话题是所有监控系统都需要处理的。当然也可以作为一个专门的产品和多种监控系统对接,专注处理告警事件,希望国内能有超越 Bigpanda、Pagerduty 的产品出现。

相关推荐
小政同学2 小时前
【NFS故障】共享的文件无法执行
linux·运维·服务器
lwf0061643 小时前
导数学习日记
学习·算法·机器学习
ch3nyuyu3 小时前
Ubuntu(乌班图)基础指令
linux·运维·网络
qeen873 小时前
【编程日记】现阶段总结
学习
挽安学长3 小时前
保姆级教程,通过GACCode使用Claude Code Desktop!
运维·服务器
daanpdf4 小时前
新视野大学英语视听说教程2第四版听力音频原文及答案
笔记
firstacui4 小时前
MGRE实验
运维·服务器·网络
白菜欣5 小时前
Linux —《开发三件套:gcc/g++、gdb、make/Makefile 全解析》
linux·运维
何中应5 小时前
Grafana如何给列表设置别名
运维·grafana·监控
MXsoft6185 小时前
运维的尽头,是把“救火”变成“算命”
运维