运维告警是运维自动化系统最为基础的功能,早期的运维监控系统只报告系统是否还活着。那个时代的数据库运维十分简陋,大部分故障都是业务部门告警,运维部门才知道,哦,数据库出问题了。那时候的领导总是希望运维部门能比业务部门早几分钟知道系统出问题了。以便于业务部门领导打电话来问的时候可以说,我们已经在恢复中了。
随着运维能力的提升,仅仅监控数据库是不是活着已经不能满足IT部门运维的要求了。“防患于未然”变成了IT部门对于运维监控的最基本的要求。不过要做到这一点并不容易,因为我们需要有很强大的监控预警能力,才能够及时发现系统的隐患。于是我们采集了更多的指标,并建立了基线,通过基线我们可以对某个指标的异常进行告警。
不过单一基线告警对于运维告警来说做起来并不容易,虽然目前主流的开源监控平台大部分都是以基线告警为主,不过基线告警的能力还是太弱了,很容易出现大量无意义的告警。于是组合规则告警这种相对更准确一些的告警替代了简单的基线告警,通过一组业务规则,几个指标之间的组合关系,更容易描述一个具体的故障场景。通过一个略微复杂的规则引擎,通过规则表达式可以实现更为准确的告警。近些年来,在D-SMART上,这种被我们称为“运维经验告警”的模式在发挥着主要的作用,已经完全替代了基线告警。
通过这种组合规则告警,我们不仅可以收敛告警数量,还可以收敛告警问题的故障原因,提供专业的诊断工具用于问题分析与溯源。这种基于规则的复合场景告警可以大大收敛告警的数量,对于运维告警能力的提升发挥了极大的作用。我们还可以把告警信息推送到企业微信上,让告警变得更好用。企业微信推送是一个十分不错的功能,可以让聊天群和告警推送紧密结合,可惜近期微信推送接口全面修改,必须将企业推送平台托管到腾讯云的专门区域,这增加了这个接口的建设复杂度,同时可能也在为商业化收费做准备。
上面是一个企业微信的消息机器人发送的告警信息。细心的朋友可能看出了这个告警似乎有点不太一样。上面的CPU使用率比较高的告警,明明是高于90%才告警,这个告警信息里当前CPU使用率才29.2%怎么也告警了。
实际上我们要告警告的并不是指标,而是数据库的异常。在十多年前,服务器资源经常处于不足的时候,大部分系统都是高负载运行的,CPU使用率长期超过90%甚至达到100%的事情经常发生,一旦发生了,就需要DBA去处置了。而现在的系统CPU资源往往都很足够,平时系统CPU使用率可能也就10%左右,出现异常时候也不见得能达到90%,因此我们设置一个90%的CPU告警阈值可能过高了。甚至我们必须针对不同的系统的不同时间段或者不同业务特点时段设置不同的告警阈值,才能够实现比较精准的告警。
基于上述原因,CPU等资源使用率过大告警无法采用传统的模式。我们需要发现系统存在的异常,那么我们就需要去检测异常,而不是检测某个具体的阈值。于是有了这种基于“异常检测”的预警。
通过上面这个告警,我们大体知道,这套系统的CPU使用率出现异常了,并且告警时的CPU使用率不算太高,不到30%。如果我手头还有更紧急的事情,我们完全可以等会儿再来处理这个异常。
比较幸运的是几分钟后我们又收到了一条告警信息,某条业务关注的关键SQL的平均逻辑读突然增加了。这很可能意味着这条SQL的执行计划发生了改变或者访问的表的数据发生了变化,而这个告警和上面的CPU使用率突然变高的告警是存在关联关系的,很可能SQL语句执行成本变高是CPU使用率突增的主要原因。
告警收敛是目前很多做AIOPS的企业都在做的工作,实际上上面的两个告警很可能是有联系的,两个告警如果能够合并那就最好了。不过以我们当前的技术水平,还做不到直接对二者进行合并,我们目前通过运维知识图谱实现了部分场景的自动化合并,不过目前因为计算量过大的问题,暂时还无法使用到运维告警上。这是为什么呢?按理说如果是SQL语句执行成本上升,导致逻辑读上升,从而导致CPU使用率上升,应该是逻辑读上升先出现,而CPU使用率上升后出现。
不做在实际的监控中想要准确的捕获到如此细微的变化是不容易的,这种情况普通的监控很难做到,只有trace能够做到。因为监控是周期性采样,哪怕监控采样周期缩短为30秒,也有可能采集不到这种先后变化的情况。
CPU使用率是2分钟一次的定期采样,而关键SQL跟踪是每5分钟一次的任务,因此关键SQL跟踪发现问题就滞后了。另外还有一些告警场景不能每次捕获到异常就告警,而是需要在某个周期内满足连续出现或者M次中至少N次这样的规则,因此顺序与关联合并变得更加复杂。同时因为数据库系统是十分复杂的系统,因此以我们目前的技术能力还无法在监控阶段就对此进行十分明确的合并。因此我们选择了同时发布多个告警,让DBA随后使用工具去做诊断发现。错误的合并很可能会对后面的问题诊断产生误导,因此我们选择让DBA和专家看到更多的细节,而不是帮他们做出错误的判断。
因为是关键SQL出现了告警,因此我们不能像上一条告警一样可以暂时搁置了。于是可以通过诊断工具去做一下分析。确实在告警期间,这条SQL的执行成本发生了变化。
监控的目的是发现异常,而在以前技术条件不具备的时候,我们只能把异常简单的定义为某个阈值,久而久之我们就误以为监控就是监控阈值了。实际上,监控技术这些年发展十分迅速,从简单的指标监控,到日志监控、态势监控,在技术上都已经日趋成熟。因此我们也应该尝试让运维告警从发现异常,自动分析异常,从而逐步向自动化处置迈进。目前的技术可能离自动化处置还有一段距离,不过我们依然能够在消减告警数量,合并告警场景上有较大的提升空间。
第一个可以用于消减告警数量的方法就是对已恢复的告警的处置策略上的优化。如果一个告警发生后,过了一会儿系统恢复了,或者说风险消失了,我们该如何处理呢?我们还去一个个死磕,要求做闭环管理,还是暂时可以不理会它呢?可能每个企业采用的不同的管理模式会对处置方法有些差异,不过随着需要运维管理的系统的数量不断扩大,哪怕仅仅对于核心系统的每个告警信息都做闭环管理也是一件成本比较高的事情。
如果我们处理这样的告警还是比较容易的,如果连已经恢复的告警也要一个个去做闭环分析,那么工作量就大了。
不过如果对于已恢复的告警就置之不理也不是一种合理的态度,如果这些问题确实是由一些深层次的隐患触发的,不去分析他们就会留下一些地雷,说不定什么时候就引爆了。这让我们陷入了两难的境地,不做闭环,可能留下隐患,做闭环管理,成本又承受不起。解决这个问题的最好的办法就是巡检。
巡检是近年来被诟病的最深的运维业务了,不做巡检除了问题有责任,做了巡检没有发现问题既浪费时间又要背责任。在这种无奈之下,一个十分重要的运维工具就被边缘化了。出现过异常,但是很快自愈的问题,实际上可以放到巡检的时候再来统一分析。巡检时,可以对数据库在某个时间段内的整体情况进行统一分析,可以对某个时间区间内的多个异常进行总体分析,因此能够发现很多系统隐患。形成巡检工作没有太大价值的观点的主要原因还是巡检的质量存在问题,如果在巡检中能够把某个时间段内因为工作量太大无法分析而问题都几种分析一下,那么巡检工作就有了新的价值了。只不过这种分析必须是自动化的,不能由人工去做。
基于此思想,我们最近的几个版本中都花了大量的工作在巡检报告的优化上,争取能够让巡检报告实用化。在最近的一系列修改中,我们发现了以前报告的大量的问题,发现问题最好的方法是让我们的专家仅仅通过阅读巡检报告就帮远程的用户分析问题,经过多次这样的迭代,报告的质量也就大大提高了。这些更新将会在本月底发布的V2.2中和大家见面。
运维告警是个做起来不难,做好十分不易的事情,我们希望通过把这些年专家积累的经验都提炼出来,融合到这个工作中去,并不断在用户那边实践,不断提升这项能力。如果大家对这项工作有兴趣,我们也可以进行交流,我们也愿意把我们实践中的发现不断地分享给大家。