AIOps对监控报警架构的挑战
负责百度智能运维(Noah)监控报警系统、通告平台;在精准报警、精准通告、报警收敛、公/私有云监控等方向具有广泛的实践经验。
干货概览
监控报警是故障发现的重要一环,也是百度在AIOps的最早切入方向之一,目前百度 AIOps 在监控报警方面已经有两个场景取得突出效果:智能异常检测和智能报警合并。
如何支撑 AIOps 算法在监控报警系统的快速落地并产生业务价值,这对监控报警架构提出了很大的挑战!本文首先介绍百度Noah监控报警的功能和业务模型,然后重点分析百度监控报警系统在落地 AIOps 过程中遇到的挑战。
百度Noah监控报警系统
首先我们介绍下百度的标准故障处理流程,如上图所示,主要分为以下7个过程:
故障发生:比如当内网机房核心交换机发生故障时,会造成内网的网络故障,从而导致产品线的流量损失。
故障发现:监控系统实时检测到产品线的流量异常。
故障通告:监控系统会通过短信或电话等渠道通知业务运维人员,产品线流量有异常。
故障止损:业务运维人员会执行故障预案,或者借助故障自愈平台智能地执行故障止损操作,以达到快速止损的目的,常见的操作是将流量从故障机房切到非故障机房。
故障定位:运维人员和研发人员一起定位故障根因。
故障恢复:当定位到问题后,运维人员开始执行修复操作,直到线上的所有服务(包括未接流量的模块)都彻底恢复正常。
故障总结:运维人员会对故障处理流程进行复盘总结,好的方面继续保持,不好的方面排期改正。
在整个故障处理流程中,监控系统主要负责故障发现到故障定位的环节;报警系统作为监控系统的子系统,主要负责故障发现和故障通告。
百度Noah报警系统最早服务于百度内部的监控平台,提供从机器、实例到上层业务等全方位、立体化的监控报警能力,已经覆盖百度的所有产品线。同时,系统面临很大的挑战,每秒需要处理千万级个数据点,线上的监控配置已经达到百万级别,每天会产生千万个报警事件,在这么大的量级下,还需保证秒级的报警时效性。
百度Noah报警系统不仅为百度内部用户服务,我们还同时为公有云和私有云服务提供监控报警能力。我们将内部强大的监控产品和运维理念输出到业界,打造了NoahEE产品(详见《百度云企业级运维平台——NoahEE》介绍 ),帮助客户一起提升运维效率和线上稳定性。另外,我们还依托报警系统孵化出了百度AIOps智能运维产品,包括智能异常检测、故障定位、报警合并等高级功能,已经落地金融、交通、互联网等行业,受到客户一致好评。
业务模型
监控报警系统的核心使命是精准报警,那报警系统是如何进行故障发现和故障通告呢?我们通过一个场景来了解下。
假设上图中的曲线是某产品线的流量指标(简称PV),其中每个点代表一个PV数据点,假设希望当PV值小于100时,异常判断结果为异常,并通告给业务运维人员。
监控报警系统会周期性地对最近一个数据点(Data)进行判断,如果PV小于100则判断结果为异常,否则判断结果为正常。当首次异常的时候(即判断结果从正常转为异常),会产生一个报警事件(Event);当异常恢复时,则将报警事件结束掉。在报警事件持续期间,会根据报警规则产生一个或多个报警消息(Message),并将报警消息渲染成容易理解的文本,通过下游发送渠道(短信、电话等)送达给运维工程师。通过这么一个流程,监控报警系统就达到了故障发现和故障通告的目的。
相应地,我们将监控报警系统拆分成以下三个子系统:
异常判断系统:主要功能是根据异常判断配置周期性地对数据进行判断,并将产生的判断结果(正常或异常)发送给下游。异常判断系统不仅需要提供基于传统四则运算的异常判断,还需要提供基于AIOps算法的异常判断。
事件管理系统:主要负责报警事件的管理工作,并基于报警事件提供防抖动过滤、报警认领、逐级通告、报警静默等功能。
通告发送系统:主要负责报警合并、渲染和发送等功能。另外为了防止下游发送网关的带宽被某些业务的突发报警流量淹没而导致其它业务的报警消息得不到及时发送,还需要提供配额和流控功能,从而保证每个业务公平地使用发送网关资源。
将监控报警系统拆分成三个子系统后,有以下两个好处:
系统功能边界清晰,具备可扩展的报警架构能力
每个子系统可以根据自身的功能特点采用不同的技术栈和部署架构,由不同的研发工程师负责研发和维护。比如异常判断系统更偏向计算逻辑,可以采用Golang或C++这类更加注重执行效率的技术栈;而事件管理和报警发送系统更偏向于业务逻辑,可以采用Java或PHP等更注重研发效率的技术栈。
每个子系统也可以独立进行功能和架构升级。比如异常判断系统需要大量的CPU资源,比较适合采用集群架构,这样方便横向扩展,增加系统吞吐能力;而通告发送系统的流量相对小些,初期可以采用主备架构,不仅架构简单可靠,而且研发和维护成本小。假设随着业务的发展,业务需要更大的报警发送能力,通告发送系统只需保证对外接口不变,独立将自身架构升级为集群架构,就可获取更大的报警发送能力。
报警功能组件化,具备灵活的商业化交付能力
每个子系统都是一个独立的功能组件,可以独立部署、升级,这样就具备灵活支持商业化交付能力。比如我们可以只将通告发送系统单独交付给商业化客户,客户通过直接调用通告发送的接口就可以获取报警合并、渲染、发送等能力。
我们遇到了哪些挑战?
通过上面的业务模型介绍,大家已经对监控报警系统有了全局的认识,那下面来详细分析落地AIOps遇到的问题。
1. 落地AIOps算法周期长,迭代成本高
我们继续来看PV指标,通过对历史PV数据的观察,我们发现不同时间段的PV大小是上下波动的,比如在早上八九点是流量高峰期,在凌晨两三点是流量低峰期,另外工作日和周末的流量大小也是不同的。这意味着,我们不可能设置统一的阈值来检测PV流量的变化情况,那么怎么办呢?
百度策略人员研发了基于鲁棒回归的无监督突升突降检测算法,这个算法不需要设置PV阈值,即可检测流量的变化。下面展示的这个公式是其中的一步,其中变量y就是真实的PV值,f(x)代表利用某种算法预测到的PV值。如果对算法细节感兴趣,可参考文章:《我们不一样!告诉你百度是如何做智能流量异常检测的》。
这类异常检测算法相对于传统的四则运算,有以下不同:
对不同类型指标在不同的场景下,算法f(x)是不相同的,特别是在初期探索阶段,我们需要快速迭代算法,以验证哪种算法效果最优。
算法f(x)会依赖根据历史数据训练到的模型,然而业务数据的特征复杂,不断变化,这意味着我们需要定期更新策略模型,以保证算法的效果。
算法f(x)对CPU资源的需求差异很大,有的算法计算量非常小,可能单个CPU核就可以运行数千个此类任务,而有的算法会引入RNN等深度学习算法,计算复杂度特别高,往往就需要独占某个CPU核。
最初我们落地这类AIOps算法时,整体的流程如上图所示:
策略工程师用Python或Matlab编写算法脚本,并在线下进行Case回溯,保证算法的普适性。
研发工程师将算法脚本改写成线上代码(C++或Java),以便在线上运行。
测试工程师对改写后的算法代码进行测试回归。
运维工程师对模块(包括算法代码和策略模型)进行发布上线。
上面的研发流程暴露出很多的问题。一方面,对我们的研发工程师要求比较苛刻,既需要看得懂策略算法,又要熟知工程研发;另一方面,算法的迭代周期比较长,经常以月为单位,可能算法刚上线,数据特征就发生了变化,导致算法失效;最后,即使算法程序迭代稳定了,但是参数模型还需要定期更新,由于参数模型和算法程序没有分离,导致后期参数模型的更新需要不断上线,提高了维护成本。
2. 报警管理需求繁杂多样,疲于应付
我们再来看下报警管理的挑战。报警管理需要处理的需求比较多,我们以一个典型的运维场景来串一下这些需求:
凌晨一点,网络运维工程师对网络进行调整,导致网络产生了短时间的抖动,这类抖动的持续时间通常都在1到2分钟左右。网络抖动导致大量的业务监控指标发生相应的抖动,从而触发报警。此时业务运维工程师就希望系统能够提供防抖动过滤功能,避免指标在短时间抖动时触发报警。
凌晨三点,由于系统日志清理机制有问题,导致集群内60%机器的磁盘占用率超过安全线,触发报警。但是报警电话未能唤醒值班工程师,最终导致大规模系统故障。因此值班工程师希望系统提供报警重复提醒功能,当值班工程师没有及时响应报警时,通过多次重复呼叫来避免报警遗漏。
但是,当值班工程师被及时唤醒并开始处理故障后,系统持续的重复提醒会对值班工程师形成很大的干扰。因此工程师们就希望引入报警认领功能,告知报警系统故障已经有人在处理,重复提醒可以停止了。
凌晨4点半,由于值班工程师是新入职的,对系统不够熟悉,日志清理的操作还未完成,导致故障持续。此时,就希望系统能够提供报警升级功能,在故障长时间未解除的时候可以通知资深的二线值班工程师介入处理。
凌晨4点50,二线值班工程师完成日志清理,故障恢复。这时,二线工程师发现日志清理操作其实是一套标准的止损操作,完全可以在发生报警时自动执行。因此希望系统能够提供报警回调功能,将来类似的问题就无需人工介入处理了。
除此之外,值班工程师可能还有断流检测、报警静默等等各种需求。
可见报警管理的需求复杂多样,如果我们不能抽象出一个可扩展的报警管理模型,我们将变得越来越被动。
3. 报警风暴淹没核心报警,束手无策
看完报警管理,我们再来看下报警风暴的挑战。
为了避免遗漏故障,运维工程师常常会在监控系统中定制大量的监控指标和报警规则,从而建立起从网络到机器、从实例到模块、再到上层业务的立体化监控。立体化的监控虽然极大提高了故障发现的能力,但是很容易导致一个故障触发大量报警,造成报警风暴。
为了让大家认识报警风暴的真面目,我们来看三个典型的场景:
机器故障:机器发生故障时,监控机器健康度的报警规则将会产生报警;然后监控机器上实例运行状态的报警规则也会产生报警;最后这些实例的上游应用模块也会受到影响,相关的报警规则也会开始报警。这样一来,一个机器的故障就可能会产生几十条的报警消息。
应用模块故障:首先这个应用模块中的所有实例都会发出报警,紧接着上游应用模块也会产生报警。当应用模块中包含的实例比较多时,这类故障常常会产生数百条的报警消息。
机房故障:会同时造成网络、机器、域名、应用模块、业务等多层次、多方面的异常报警,产生的报警消息可以多达数万条。
我们可以看到,这三种典型故障对值班工程师都非常的不友好。他们的手机会被短信和电话轰炸,与此同时大量的报警消息却并不能帮助他们迅速寻找根因和制订止损方案。对大量报警消息先进行有效地组织,然后再发送,就成为值班工程师的一大需求。
/// <summary> /// 验证CRC16校验码 /// www.javachenglei.com </summary> /// www.wanyayulez.cn <param name="value">校验数据</param> /// <param name="poly">多项式码</param> /// <param name="crcInit">校验码初始值</param> /// <returns></returns> public static bool CheckCRC16(byte[] value, ushort poly = 0xA001, ushort crcInit = 0xFFFF) { if (value == null || !value.Any()) throw new ArgumentException("生成CRC16的入参有误"); var crc16 = GetCRC16(value, poly, crcInit); if (crc16[crc16.Length - 2] == crc16[crc16.Length - 1] && crc16[crc16.Length - 1] == 0) return true; return false; } /// <summary> www.yongshiyule178.com /// 计算CRC16校验码 /// </summary> /// <param name="value">校验数据</param> /// <param name="poly">多项式码</param> /// <param name="crcInit">校验码初始值</param> /// <returns></returns> public static byte[] GetCRC16(byte[] value, ushort poly = 0xA001, ushort crcInit = 0xFFFF) { if (value == null || !value.Any()) throw new ArgumentException("生成CRC16的入参有误"); //运算 ushort crc = crcInit; for (int i = 0; i < value.Length; i++) { crc = (ushort)(crc ^ (value[i])); for (int j = 0; j < 8; j++) { crc = (crc & 1) != 0 ? (ushort)((crc >> 1) ^ poly) : (ushort)(crc >> 1); } } byte hi = (byte)((crc & 0xFF00) >> 8); //高位置 byte lo = (byte)(crc & 0x00FF); //低位置 byte[] buffer = new byte[value.Length + 2]; value.CopyTo(buffer, 0); buffer[buffer.Length - 1] = hi; buffer[buffer.Length - 2] = lo; return buffer;
总 结
本文首先介绍了百度Noah监控报警系统功能和业务模型,然后结合案例场景分析了我们在落地AIOps时遇到的问题,让大家对监控报警系统的现状有一个直观的认识。我们将在下篇文章中讲解如何来解决这些挑战,敬请期待。
AIOps对监控报警架构的挑战的更多相关文章
- SQL Server监控报警架构_如何添加报警
一.数据库邮件报警介绍 数据库邮件是从SQL Server数据库引擎发送电子邮件企业解决方案,使用简单传输协议(SMTP)发送邮件.发送邮件进程与数据库的进程隔离,因此可不用担心影响数据库服务器. 数 ...
- Kubernetes集群的监控报警策略最佳实践
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/M2l0ZgSsVc7r69eFdTj/article/details/79652064 本文为Kub ...
- vivo 容器集群监控系统架构与实践
vivo 互联网服务器团队-YuanPeng 一.概述 从容器技术的推广以及 Kubernetes成为容器调度管理领域的事实标准开始,云原生的理念和技术架构体系逐渐在生产环境中得到了越来越广泛的应用实 ...
- node服务的监控预警系统架构
需求背景 目前node端的服务逐渐成熟,在不少公司内部也开始承担业务处理或者视图渲染工作.不同于个人开发的简单服务器,企业级的node服务要求更为苛刻: 高稳定性.高可靠性.鲁棒性以及直观的监控和报警 ...
- Windows Azure功能更新:弹性伸缩(autoscale)、监控报警、移动服务及网站服务商用、新的虚拟机镜像
Windows Azure功能又更新了.此次更新包括1项重要更新和两个功能更新: 重要更新:云服务.网站支持按策略进行弹性伸缩 功能更新:两个预览版的服务(网站和移动)进入商用,虚拟机服务支持SQL ...
- Python-WXPY实现微信监控报警
概述: 本文主要分享一下博主在学习wxpy 的过程中开发的一个小程序.博主在最近有一个监控报警的需求需要完成,然后刚好在学习wxpy 这个东西,因此很巧妙的将工作和学习联系在一起. 博文中主要使用到的 ...
- Ganglia与Centreon整合构建智能化监控报警平台
一.智能运维监控报警平台的组成 随着大数据时代的来临,运维工作的难度越来越大,每个运维人员都要面临不计其数的服务器和海量的数据,如何保证众多服务器和业务系统稳定高效地运行并尽量减少死机时间,成为考核运 ...
- linux下日志文件error监控报警脚本分享
即对日志文件中的error进行监控,当日志文件中出现error关键字时,即可报警!(grep -i error 不区分大小写进行搜索"error"关键字,但是会将包含error大小 ...
- zabbix实现企业微信监控报警
一.zabbix基本说明 简介:zabbix基于Web界面的分布式系统监控的企业级开源软件.可以监控各种系统与设备,网络参数,保证服务器设备安全运营:提供灵活的通知机制.如果检测到的指标不达标,就实现 ...
随机推荐
- SQLAlchemy建立数据库模型之间的关系
一对多关系 多对一关系 多对多关系 一对一关系 一对多关系(一个作者,多篇文章) ## 一对多关系,单作者-多文章,外键不可少 ## 外键(ForeignKey)总在多的那边定义,关系(relatio ...
- 158-PHP strstr函数输出第一次出现字符串的位置到字符串结尾的所有字符串
<?php $str='PHP is a very good programming language!'; //定义一个字符串 echo '第一次出现字母l的位置到字符串结尾的所有字符串'.s ...
- Java虚拟机之内存模型
一.java并发基础 在并发编程中存在两个关键问题①线程之间如何通信 ②线程之间如何同步. 通信 通信是指线程之间以何种机制来交换信息.在命令式编程中,线程之间的通信机制有两种:共享内存和消息传递. ...
- CSS - input 美化
input{ padding: 20px; width: 100%; height: 5vh; margin-bottom: 2vh; border-radius: 10vw; border: 0; ...
- Java UDP发送与接收
IP地址?端口号?主机名? 什么是Socket? 什么是UDP? 什么是TCP? UDP和TCP区别? 以上问题请自行百度,有标准解释,此处不再赘述,直接上干货! 实例: 发送端: public cl ...
- 欧拉回路--P2731 骑马修栅栏 Riding the Fences
实在懒得复制题干了 *传送 1.定义 *如果图G(有向图或者无向图)中所有边一次仅且一次行遍所有顶点的通路称作欧拉通路. *如果图G中所有边一次仅且一次行遍所有顶点的回路称作欧拉回路. *具有欧拉回路 ...
- Linux文件和目录的属性及权限
Linux文件和目录的属性及权限讲解 文字解释: 第一列:inode索引节点 第二列:文件类型及权限 第三列:硬链接个数 第四列:文件或目录所属的用户(属主) 第五列:文件或目录所属的用户所归属的组( ...
- 兼容iphonex底部那个
@media only screen and (device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ra ...
- vue的开发中v-for报错 [vue/require-v-for-key] Elements in iteration expect to have 'v-bind:key' directives.
用的VS Code 工具,安装了vetur插件,报错了如下 [eslint-plugin-vue] [vue/require-v-for-key] Elements in iteration expe ...
- axios基础介绍
axios基础介绍 get请求要在params中定义,post要在data中定义.