传统的运维监控系统是以基线为核心判断系统是否存在某个问题并进行告警的。这种模式最大的问题就是基线如何设置十分困难,如果我们自己日常运维的系统,我们对基线十分了解,那么我们可以给出相对合理的基线,实现较为精准的告警。
不管如何设置,单指标告警总是不准确的,因为我们无法知道系统什么时候存在问题。我们以每秒逻辑读这个指标来做些分析吧。每秒逻辑读这个指标在二十年前监控Oracle数据库是否存在把系统撑爆的风险是十分有效的,那时候的服务器的CPU资源总是最紧张的。当逻辑读变得很高的时候,我们就需要告警让DBA介入运维了。这时候杀掉几个大查询往往就能挽救系统。实际上现在很多国产、开源数据库运维领域,这个指标异常的监测依然十分有效。
传统的基线模式只能设置一个阈值来判断逻辑读是否异常,这个值往往会设置的不准。因此我们会考虑采取一种新的方式来设置这个告警规则。
上面的表达式的含义是当逻辑读是该指标最近一小时平均值的N倍,并超过基线预警高值的M倍的时候产生该指标的故障预警。这主要是为了避免设置不合理的阈值的时候产生阈值设置过高则有问题不报警,设置过低,则经常误报的问题。我们不需要再给系统设置一个预警的实际阈值了,而是根据系统中计算的当前一小时平均值来做判断。加上右面的这个条件是为了防止系统从闲时突然变忙碌时的一个临界状态。这个状态往往是正常的。
通过这样的改造之后,逻辑读预警的误报问题得到了很好的缓解,不过问题又来了。N值得设置依然十分具有挑战性,设置的不合理依然会产生大量的误报。如果DBA运维的系统十分有限,而且对系统的这些指标的波动情况十分了解,那么设置合理的N还是不难做到的,不过在我们的用户中并不总是这样,很多运维人员根本不知道该如何去设置这个参数。另外一方面,随着运维压力日益增大,一个DBA可能要监控上百个甚至数百个数据库,每个数据库都去这么玩,工作量太大了。
我们也一直想把异常检测算法引入到故障模型中来,不过一直因为算力过大的问题,没法大规模应用。自从考虑采用异常检测指标化的策略后,这个问题才得到很好的解决。
对于指标通过计算趋势将各种状态转化为数字,比如3代表某个指标急剧上升。那么我们就可以利用这个新的指标来完成对上面的哪个表达式的改造了。
新的故障模型倍定义为当每秒逻辑读指标超过一个绝对大的值(比如1000万、2000万等),或者每秒逻辑读指标急剧上升,并且每秒逻辑读大于一个门槛值(比如50万),则说明系统的应用可能存在一定的异常。这种异常很可能是应用负载过大,也可能是应用出现了BUG,或者某条关键SQL的执行计划出现了问题。
可能有些朋友还是有些不解,这里不也存在两个参数吗,似乎这个表达式的设置和以前并没啥不同,不同的系统这些参数如何设置呢。实际上这两个参数是补充型的,第一个设置为一个绝对高值,是为了避免指标出现缓慢增长,累计达到了一个较高的值,这个值对于当前的硬件是致命的,因此比较容易设置,比如设置2路服务器为1000万,4路服务器为2000万,大体是能够发挥作用的,而参数2是为了避免小负载波动的门槛值,比如从1000增长到20000,很可能被监测为急剧增长,不过这种增长对系统来说是没有太大影响的,为了避免此类现象误报,需要设置一个门槛,一般来说10万,20万就可以避免了,设置起来也相当容易。
经过改造后,一旦出现异常负载,系统就能够很好的告警了,而那些容易误报的情况也不会再出现了。而且这个故障模型可以适应于不同的应用系统,不同类型的负载,不需要做个性化的调整。对于我们目前运维大量的系统的DBA来说,就省了很多事。实际上只要在我们的普罗米修斯、Zabbix等系统中,将异常分析算法进行指标化改造,要想实现类似D-SMART中智能预警的功能也并不难。其重点是异常分析算法的设计与异常分析指标化的设计。