Posted in

故障 1min 发现率 100%,去哪儿秒级监控预警落地实践_AI阅读总结 — 包阅AI

包阅导读总结

1. 秒级监控、watcher、监控预警、架构优化、报警规则

2. 本文主要介绍了去哪儿秒级监控预警的落地实践,包括整体架构、面临的挑战及解决方案,如存储选型、客户端改造、服务端优化等,还提及了秒级面板编排、接入策略、通知模板和报警规则配置。

3.

– 整体架构

– 包括数据采集、数据查询、dashboard查看和报警四个部分,数据点为分钟维度。

– 面临挑战

– 存储IO过高和占用空间过大。

– 对Graphite协议的兼容性问题。

– 需对整个监控链路进行修改以适应秒级监控。

– 解决方案

– 存储改造:选择VictoriaMetrics作为时序数据库,并进行存算分离改造。

– qmonitor客户端:进行多份数据计算和存储,生成多个快照。

– 服务端:将任务调度功能转移到Worker节点,采用新开发模式。

– 秒级面板编排:依据核心监控指标提前编排。

– 接入策略:采用白名单添加秒级指标,新增秒级监控数据源。

– 通知和报警:新增秒级通知检测模板,精细化设置报警规则并区分工作日与节假日。

思维导图:

文章地址:https://mp.weixin.qq.com/s/rgwz4t9Z5esGStBxpzJLaw

文章来源:mp.weixin.qq.com

作者:宋倩倩&梁成琰

发布时间:2024/6/24 11:14

语言:中文

总字数:7299字

预计阅读时间:30分钟

评分:85分

标签:监控,故障检测,去哪儿旅行,秒级监控,预警


以下为原文内容

本内容来源于用户推荐转载,旨在分享知识与观点,如有侵权请联系删除 联系邮箱 media@ilingban.com

上图为watcher业务监控的整体架构图,从图中可以看出,整体架构包括四个部分,分别为数据采集、数据查询、dashboard查看和报警。

数据采集:主要负责业务指标数据的收集和存储,在存储方面,watcher使用的是时序数据库Graphite;数据采集使用的是自研的采集器qmonitor,包括server、client、manager三个部分,其中manager为采集配置中心,client负责收集业务侧指标数据并上报server,server负责聚合数据并将数据存入时序数据库。

数据查询:API层,主要负责查询指标数据,包括简单指标查询和复杂聚合指标查询。查询api是在Graphite api的基础上进行了二次开发,并新增了指标源信息数据库,以满足分集群查询以及多种复杂条件查询。

dashboard:可视化层,用户可以通过dashboard进行指标数据查看、面板配置、报警编辑等操作,基于grafana深度开发。

报警:报警服务,报警状态检测负责对用户所配报警进行规则判定,若满足报警条件,则将此报警置为critical或warning状态;报警通知服务则使用了icinga服务,支持电话、qtalk通知(qtalk为去哪儿旅行自研办公软件)、短信通知,支持开关报警、downtime等。

以上四个部分,无论是qmonitor、数据存储、查询以及报警,数据点都是分钟维度的,若想支持秒级监控,便涉及到了全链路的修改和变更。而在秒级监控项目启动之前,基于以上架构,我们对watcher监控平台进行了摸排梳理,在此过程中,我们发现要想支持秒级监控,需要解决以下三方面挑战:

挑战一:存储IO过高和占用空间过大的问题

当前分钟级监控的时间序列数据库(TSDB)使用的是Graphite的Carbon和Whisper。由于Whisper的空间预分配策略和写放大问题,导致了磁盘IO压力过大,同时也占用了过多的存储空间。秒级监控带来的是精度的提升,但也同时会导致存储和写入的激增,因此解决监控数据存储的问题成为了首要任务。

挑战二:对Graphite协议的兼容性问题

目前分钟级监控的存储使用的是Graphite,监控数据的采集和查询协议都是基于Graphite的。为了尽可能在使用秒级监控时让用户无感,在构建秒级监控系统时,必须要考虑到对Graphite协议的兼容性问题。

挑战三:需要对整个监控链路进行修改以适应秒级监控的挑战

watcher现有的数据采集、数据存储和告警系统都是基于分钟级别设计的。如果要实现秒级监控,就需要对从数据采集到存储,再到告警的整个链路进行大规模的修改。

接下来,我们将会从存储改造、qmonitor客户端、服务端指标采集优化等几个部分进行重点阐述。

1) 存储方案选型

由于当前存储Graphite不能支持秒级监控更大的并发,因此我们探索了新的存储方案。在综合了所有限制条件后,我们在选取存储方案时重点对M3DB和VictoriaMetrics(以下简称“VM”)两种解决方案进行了评估。选择它们是因为它们都支持Graphite协议。

优势

1.高压缩比,高性能

2.可伸缩

3.支持Graphite协议以及部分聚合函数

1.高性能,单机读写可达千万级指标

2.每个组件都可以任意伸缩

3.原生支持Graphite协议

4.部署简单

5.社区活跃度高,更新迭代快

劣势

部署维护相对复杂

针对Graphite聚合读场景下,性能会严重下降


在经过详细的比较后,我们发现无论是M3DB还是VM,都具有较高的压缩率和出色的存储和查询性能,都能够满足我们的需求。而考虑到M3DB的部署和维护相对复杂,而VM的每个组件都可以任意伸缩,部署较为简单,且社区活跃度也比较高。另一方面,VM在压力测试后展现出了较高的读写性能:单机读写可以支持高达1000万级的指标。因此最终我们选择了VM作为我们的时序数据库。

2)VM存在的问题:聚合读场景下性能下降严重

我们在对VM进行压力测试的过程中,发现其在进行单一指标查询时,性能表现出色,完全满足我们的查询需求。

压测表现:

服务器配置:32核CPU,64GB内存,以及3.2TB的SSD存储。

服务部署:vmstorage、vminsert、vmselec。

设定每分钟写入的指标数量1000万,查询QPS 2000。

压测发现,平均响应时间为100ms,写入一天的数据后,磁盘使用量约为40GB,而主机Load保持在5到6之间。

但是在进行复杂指标查询时,比如涉及到函数查询和聚合指标查询,性能会显著下降,甚至有时会超时。

3)改造方案:存算分离改造

为了解决这个性能问题,我们进行了一些改造探索。依据上文中的压测结果,VM在单一指标的查询上表现优秀,因此我们决定让VM专注于单一指标的查询,而复杂指标的查询和聚合由CarbonAPI来承担。选择VM并进行存储和计算分离改造后,成功解决了秒级监控的存储、查询和写入问题。

为什么是CarbonAPI

CarbonAPI是一套开源工具,不仅支持Graphite协议,还支持Graphite中大部分的聚合计算和聚合指标解析查询,但它对聚合指标解析查询的实现并不完整。

由于CarbonAPI是无状态的,可以任意扩展,研发团队就可以定制化一些功能,如监控处理、数据剪裁等。经过改造后,实现了存储和计算的分离,以支持非常高的查询QPS。

做了哪些改造


添加一个指标名元数据DB,每当一个指标写入VM时,会将指标名称和查询URL等信息存入元数据DB。然后,CarbonAPI在解析时,会将带有多个标签或函数的指标解析为单一指标,再放入VM进行查询。这样做有效地提升了VM的查询性能。

1)当前架构


上图所示为watcher当前数据采集架构,若想支持秒级监控,其存在的问题是:指标仓库和调度器不满足需求。watcher现有的分钟级监控主要依赖公司自主研发的SDK来进行数据采集,并未采用诸如开源的Prometheus SDK之类的工具。若想支持秒级监控,我们发现客户端存在一些问题:

问题一:调度器问题

Counter在完成一个指标计数后,会将指标及其相关数据存储在本地的Metric仓库中。调度器会在每分钟的固定时间从指标仓库中提取数据,生成一个快照并将其存储起来。当服务端需要采集客户端的数据时,它将提取这个快照,而不是直接从仓库中获取实时数据。这种做法与开源社区的实践有所不同。我们选择使用快照而非实时数据,主要是为了按分钟级别对齐数据,以便于服务端的处理。无论何时,无论服务端进行几次数据拉取,获取的都是同样的前一分钟的数据,且这些数据是固定的,不会再发生改变。

问题二:指标仓库问题

指标仓库只支持分钟级的数据存储,这是因为我们之前的设计都是基于分钟级别的。

2)解决方案:客户端进行多份数据计算和存储,生成多个快照

①方案选型

在对客户端进行改造的过程中,我们设计了两种方案。

方案一:参考了Prometheus的模式,即不生成快照,而是直接获取仓库的实时数据,仅进行数据累加或记录。当客户端拉取数据时,可以选择将原始数据存入TSDB,或自行进行增量计算。

优点:客户端节省内存。

缺点:

如果客户端自行进行增量计算,它需要获取前一分钟或者前一段拉取间隔的数据,然后才能进行增量计算。如果直接将原始数据存入TSDB,每次用户查看数据时,需要自行进行增量计算,这将影响用户体验。

尽管这种模式可以节省客户端内存,但它将引发我们的采集架构发生巨大变化,并可能存在数据精度问题。

方案二:仍然依赖客户端生成快照,但是会进行多份数据计算和存储,并生成多个快照。

优点:采集架构改动小,没有数据精度问题,server压力小。

缺点:存储秒级的数据会占用更多的内存。

由上面对比可以看出,方案二相比方案一来说现有采集架构改动小,不会存在数据精度问题,数据聚合计算分布在client端,server压力小。虽然会占用更多的内存,但我们也对这一问题进行了优化,对于Counter类的数据,由于它本身就是一个Int或者Float64的数据,其本身占的内存就不多。而Timer类型的数据我们采用了Tdigest数据采样算法进行数据压缩,将原本可能有1000个数据点的数据,缩减到100个数据点。通过这样的优化,我们发现对内存的占用是可以接受的。

因此,综合以上考虑,我们最终选择了方案二。

②改造后的架构

选定方案二后,我们对客户端进行了改造:


改造一:引入一个新的计算层,这个计算层实现了两个功能

功能一:数据采样。

功能二:判断指标是否需要进行秒级采集。

目前我们只对核心的订单类和系统的P1级指标进行秒级采集,因为如果对所有指标都进行采集,资源消耗将非常大。在计算时,它会同时计算秒级和分钟级的数据。

改造二:调度器的改造,增加了一个快照管理器,用于管理多个快照。

服务端在拉取数据时,会根据参数选择拉取不同的快照。配置管理服务则作为服务端和客户端交互的接口,可以将秒级的配置实时推送给客户端。

经过这样的改造,我们的客户端现在能够满足我们的需求,可以进行秒级的计数。

1)当前架构

当前架构存在问题:数据断点和高资源消耗

问题一:秒级数据采集出现断点

在我们的原始架构中,我们采用了Master-Worker模式,这是一个相对简单但功能强大的设计。在这个架构中,Master充当一个全局调度器,定期从数据库拉取所有任务,并通过消息队列将任务分发给各个Worker。这是一个经典的生产者消费者模式,其优势在于Worker可以轻易地进行扩展,因为它们是无状态的,如果任务过多,可以简单地增加Worker以满足需求。

然而,当我们尝试进行秒级采集时,我们遇到了一些问题。我们有数以十万计的任务,通过消息队列发送任务时,有时需要长达12秒的时间。这与我们的秒级采集需求不符,因为如果任务的发送就需要12秒,而我们的采集间隔只有10秒,那么秒级数据采集就会出现断点。

问题二:高资源消耗

系统是使用Python开发的,使用了多进程/多线程的模型。当需要拉取大量的节点数据并进行聚合计算时,CPU的消耗过高。需要一个合理的解决方案,既能满足秒级采集的需求,又能有效地管理资源消耗。

2)解决方案:将任务调度的功能转移到Worker节点

将任务调度的功能转移到了Worker节点上,尽管使得Worker变成了有状态的服务,但是如果一个Worker出现故障,Master会监听到这个变化并将该Worker的任务重新分配给其他节点。

3)改造后架构

该架构仍然可以方便地进行扩展,同时我们选择了Go + Goroutine这样的开发模式,因为它更适合高并发的场景。经过改造后,系统现在可以支持分钟级和秒级的数据采集。

架构介绍:

①去掉了消息队列,依然保持了Master-Worker的模式。

②增加了任务分区的功能到Master节点中。

例如,我们有数以十万计的任务,通过任务分区,可以清楚地知道有多少个Worker节点,然后将不同的任务分配给不同的Worker,这是通过Etcd进行分区设置实现的。

③Worker节点会监听etcd的事件,一旦检测到事件,它就会知道需要执行哪些任务,比如ID为1到1000的任务。

④Worker会获取这些任务,并将任务缓存到内存中,然后开始执行。

在已经明确了秒级监控主要监测核心业务与核心指标变化的前提下,该如何编排秒级面板?

不管是面向整个业务,还是仅面向一个项目,不同的业务体量差异,都可以根据各自特点梳理出对应的核心监控面板。譬如只关注业务最核心的指标,又或者是业务的关键过程指标。单个监控面板上可以包含一个监控指标,也可以包含多个监控指标,通过不同纬度来综合反应业务/项目情况。

在避免报警风暴和不必要的资源浪费的同时,提前编排秒级面板,可以依据核心监控指标推导出受影响的应用范围,从而评估大概的sdk升级成本,人力投入成本,方便下一步工作的开展。

秒级监控的实现涉及到了指标采集sdk的修改,因此若想要使用秒级能力,需要升级对应应用的sdk,而我们借助tc同学配套的组件升级机制,可以实现修改版本、beta测试、灰度验证到线上全量上线的全流程自动化。

为了方便大家的接入和使用,我们主要做了以下两点策略:

1)秒级指标采用白名单的方式添加

watcher指标的采集使用的是pull的方式,对于业务类指标,需要开发同学在代码里调用打点方法,并在监控平台配置应用拉取的参数包括环境、端口号、路径等,为了减少开发同学在使用秒级监控时额外增加代码修改成本和配置成本,我们使用了白名单机制。具体实现如下图,新增一个秒级监控metadb,保存指标白名单,并推送到应用sdk,对于配置了白名单的指标,sdk在记录分钟级打点的同时,也会记录秒级的打点,无需改动代码和拉去配置,做到了秒级指标的一键添加。


2)dashboard新增秒级监控数据源,并在panel加以区分

我们在watcher新增了秒级数据源,提供了快速切换数据源的配套工具,以便于大家快速配置秒级监控面板和报警。并且在watcher的panel维度增加了数据源标识以区分分钟级和秒级监控面板。

1)通知模版

watcher报警通知服务使用的是icinga集群,为了实现报警通知的秒级触达,我们新增了秒级的通知检测模版SL1、SL2,两类模版的检测频率和秒级指标数据的采样频率保持一致。其中SL1在报警状态改变后会立即同时电话通知和qtalk通知(qtalk是去哪儿旅行自研办公协作平台),SL2在报警状态改变后会立即进行qtalk通知,3分钟后进行电话通知。业务线同学可以根据报警级别配置不同通知模版。

2)报警规则配置策略

如下图所示,相同指标在分钟级和秒级的监控表现,可以直观的看出,秒级监控指标的数据趋势更加陡峭。

分钟级监控指标:

秒级监控指标:

报警规则配置会直接影响秒级报警的准确和有效。在分钟级报警规则配置方式的基础上,秒级还要:

①精细化设置报警规则,避免报警未报问题。譬如:观察指标趋势,根据实际情况尽可能的细化时间间隔,在流量高峰期间,设置不同时间间隔的报警规则。

为什么要精细化设置报警规则?

如上如所示,秒级监控指标的数据趋势更加陡峭,如果参考分钟级来设置报警规则,流量在高峰期间掉了一个坑,指标累计下降造成的损失,秒级并不能更快地发现并预警。

②区分工作日与周末节假日,避免因流量降低造成的误报问题