昨天有朋友在微信群里问我数据库指标告警的故障收敛怎么做才能真正落地。说实话,很多做智能运维的公司虽然号称能够很好的实现故障告警收敛,但是都受限于场景。在大多数情况下,在一个系统中,系统中多个IT部件的故障是通过算法根据时间、顺序、波动曲线和相关元素进行收敛的。这种收敛在某些场景下是有效的,但也有一定的误判和遗漏,但总体来说还是可以的,有一定的实际作用。网友们的问题不是如何将各个IT组件对同一个问题在一个系统中的告警进行合并,而是针对一个具体的运维对象,他特指数据库。如果把这个问题放到具体的运维对象中,比如DBA面对的数据库系统,那么这个问题就完全不同了。当时朋友举了个例子,系统中CPU使用率为98%,表空间使用率为99%,应用响应时间异常。这种情况下如何进行告警收敛?在我们实际的生产环境中,问题可能会更加复杂,因为大多数IT系统都是在带病工作的,我们称之为亚健康状态。系统亚健康状态在实际生产环境中往往是常态,但这些小问题不会引起大波澜,所以我们不去关注,甚至察觉不到,也不一定需要立即做闭环解决方案。然而,就像大量无症状的新冠感染者隐藏在人群中一样,因为他们本身并没有发病,所以没有引起社区或社会的重视。如果我们不对所有员工进行核酸检测,那么这些可能会导致重大传播的潜在风险。我们无法感知威胁。只有当有症状的患者被发现或有症状时,周围环境才能感知到。但是,系统的监控和运维是一件非常复杂的事情。除了管理程序,还有成本问题。因此,我们总是把主要成本放在急需解决的问题上。对于不是特别重要的告警信息,大部分企业已经无法做到闭环管理。试想一下,如果一个人管理几十个甚至上百个数据库系统,你能不能对每天产生的几千条甚至几万条告警信息进行闭环管理?其实在实际的生产环境中,即使已经暴露了,比如CPU使用率是98%,是不是说明系统有问题呢?如果表空间使用率为99%,并不代表一定有问题。如果表空间包含静态数据,或者数据文件是自动扩展的,那么100%的表空间使用率没什么大不了的。让我们看看上面的例子。USERS表空间使用率为97.75,容量为32GB。其实你看oracle的dba_free_space,这个tablespace已经是100%了,只是因为数据文件自动扩容了。监控系统根据ASM磁盘组的容量,自动为该表空间分配32GB的动态容量,并自动调整表空间使用率为97.75。从这种动态调整来看,首先要注意的是指标的准确性和有效性。由于AUTOEXTEND功能的存在,以及ASM磁盘组对文件EXTEND的限制,如何计算准使用率非常关键。如果这个指标不准确,那么后续的监控和报警就会变得很虚幻。除了指标的准确性,我们还需要注意什么?其实很多指标都不能很好的反映风险,比如表空间使用的问题。让我们再看看下面的例子。可以看到我们引入了一个“表空间容量风险”的评估指标,通过这个指标对表空间进行风险告警。该指标比表空间使用率具有更高的准确性。整个系统的表空间利用风险为0,为最低级别,说明没有风险。我们刚才看到的使用率为97.75%的USERS表空间的风险等级也是如此。为什么会这样?USERS表空间中存储的数据大部分是只读数据,增长速度极低,每次增长的数量也很少。目前,它可以在不扩展的情况下长期使用,因此无需立即报警。这种评估可以大大减少误报,但也可能带来新的问题,即如果有人要向USERS表空间导入大量数据,会立即报错。因此,表空间使用率高的情况不能完全忽略。我们会在日巡、周报、月报中指出这个问题,而不是在日常告警中不停的去告警,这样也可以起到提醒运维人员的作用,不用在告警中发短信半夜虚惊场。从以上例子可以看出,准确有效的指标体系是实现故障告警收敛的最基础工作。事实上,指标的准确性也可以大大提高告警的准确性,从而降低运维成本。完成这一步之后,接下来我们应该做什么呢?让我们回到前面的例子。应用程序是否变慢,是正常还是异常?这三个指标之间是否存在相关性?有什么样的相关性?事实上,如果要针对这种场景做告警收敛,还是摆脱不了专家的经验和系统在实际运行环境中的运行特性。对于数据库来说,如果表空间满了,无法写入数据,应用就会报错,系统负载就会下降,数据库的并发负载就会下降,甚至CPU占用率可能会直线下降。一旦某些系统写入数据失败,会话将重新启动,新连接到数据库的数量将增加。因为数据库无法写入,所有新建连接都会失败,连接失败率会急剧上升。还是会很正常。如果我们能够梳理出这种场景,那么我们一定能够很好的将这种场景中的十几种指标异常归类,汇聚成告警,直接告知故障根源。如果能够根据这些指标的时间序列对这些指标的异常检测进行重新分类,则可以更准确地收敛故障场景,将告警的准确率提升到更高的水平。这种对运行特征的梳理,可以由专家根据以往的故障案例或经验进行梳理,也可以通过算法自动分类抽象场景。回到CPU占用率高的问题,如果某个工作窗口的CPU占用率突然上升了1倍或数倍,并不一定意味着数据库系统或应用程序出现了问题,必须由操作介入和维修人员。但是,如果CPU使用率持续高于平时,或者CPU使用率突然低于某个benchmark,这意味着系统出现问题的几率远高于一个或几个采样点的高值。因此,我们不应该直接使用CPU占用率这个指标来进行告警,而是通过实时计算生成CPU占用率过高的风险或者CPU占用率异常的风险等指标进行预警,这样会有更好的效果。.当然,在实际实现中,可以构建一系列的规则模型或专家模型,用这些模型来描述一个场景的成本要比将每个场景都做成一个指标要低得多。一些常见的故障场景往往可以做成独立的指标,从而降低分析的复杂度。对于一些非通用的、系统相关的或用户私有的故障模型,可以采用其他方法构建。一旦构建了这些故障模型,我们就可以忽略指标和基线的警告。运维人员只需要面对故障模型的预警进行闭环管理,这也是实现故障告警收敛的一种实现方式。实际案例中,在一百多个系统、上百个数据库、中间件的运行环境中,每天收到的告警只有几十个,需要立即闭环处理的事件数量基本都是个位数。当然,这种方法也有缺点,就是会漏掉一些未知的风险。我们采用了健康模型预警的方式来弥补。当系统健康度急剧下降时,会产生模糊状态告警。这种告警需要运维人员做状态巡检来定位问题。如果定位到明确的问题,则可以将其再次抽象成新的故障模型。通过这样的不断迭代,我们的运维告警越来越准确。
