传统运维监控系统以基线为核心,判断系统是否存在问题并发出告警。这种模式最大的问题是如何设置基线非常困难。如果我们对自己的日常运维系统的基线非常了解,那么我们就可以给出一个相对合理的基线,实现更准确的告警。不管怎么设置,单一的指标告警总是不准确的,因为我们无法知道什么时候系统出了问题。让我们通过每秒逻辑地读取该指标来进行一些分析。每秒逻辑读数这个指标在二十年前就非常有效地监控了Oracle数据库是否存在系统爆仓的风险。那时候,服务器的CPU资源一直是最紧张的。当逻辑读变得很高时,我们需要提醒DBA介入运维。这时候干掉几个大查询,往往可以挽救系统。其实在国内和开源的很多数据库运维领域,异常指标的监控还是很有效的。传统的基线模式只能设置一个阈值来判断逻辑读是否异常,而这个值往往设置不准确。因此,我们会考虑采用一种新的方式来设置这个告警规则。[metric,2189030]/[metrichouravg,2189030]>[num,$1]&&[metric,2189030]>[bslupper,2189030]*[num,$2]上面表达式的意思是当逻辑读为当该指标为最近一小时平均值的N倍且超过基线预警高值的M倍时,将产生该指标的失效预警。这主要是为了避免阈值设置过高,阈值设置过高不报警,阈值设置过低,频繁误报的问题。我们不再需要为系统设置一个实际的预警阈值,而是根据系统计算出的当前一小时平均值来进行判断。增加右边的条件是为了防止系统突然由空闲变忙而出现临界状态。这种状态通常是正常的。经过这样的改造,逻辑读警告的误报问题得到了很好的缓解,但是问题又来了。N的值的设置还是很有挑战性的,不合理的设置还是会产生大量的误报。如果DBA运维的系统非常有限,并且对系统中这些指标的波动情况有很好的了解,那么设置一个合理的N并不困难。但是,在我们的用户中,情况并非总是如此。很多运维人员根本不知道这个参数怎么设置。另一方面,随着运维压力越来越大,一个DBA可能要监控上百个甚至上百个数据库。为每个数据库执行此操作的工作量太大。我们一直想将异常检测算法引入到故障模型中,但由于计算能力过大的问题一直未能大规模应用。自从考虑了异常检测索引策略后,这个问题就得到了很好的解决。对于指标,通过计算趋势,将各种状态转化为数字,比如3,代表某个指标大幅上涨。那么我们就可以使用这个新的指标来完成上面which表达式的转换。新的故障模型定义为当logicalreadspersecond指标超过一个绝对大的值(比如1000万,2000万等),或者logicalreadspersecond指标急剧上升,逻辑readspersecond更大超过一个阈值(如5010,000),则意味着系统的应用可能存在一些异常。这种异常很可能是因为应用负载过大,或者是应用有bug,或者是某个关键SQL的执行计划有问题。可能有些朋友还有点疑惑,这里有两个参数,好像这个表达式的设置和之前没什么区别,不同的系统怎么设置这些参数。其实这两个参数是相辅相成的。第一个设置为绝对高值,是为了避免指数增长缓慢,累计值达到高值。这个值对当前硬件来说是致命的,所以比较容易设置。比如设置2路服务器为1000万,4路服务器为2000万。一般都能起到作用,参数2是避免负载小波动的阈值。比如从1000增加到20000,很可能监测到不是急剧增加,但是这种增长对系统影响不大。为了避免此类现象的误报,需要设置一个阈值。一般来说,10万或者20万都可以避免,而且设置起来还是比较容易的。改造后,一旦出现负载异常,系统就能很好的报警,那些容易误报的情况将不再出现。此外,该故障模型无需单独调整即可适应不同的应用系统和不同类型的负载。对于目前运维大量系统的DBA来说,节省了大量的工作量。其实只要在我们的Prometheus、Zabbix等系统中对异常分析算法进行索引,不难实现类似于D-SMART中智能预警的功能。重点是异常分析算法的设计和异常分析指标的设计。
