不谈笼统的智能运维,聊聊我在用的异常测量核心算法
优采云 发布时间: 2020-08-26 05:40不谈笼统的智能运维,聊聊我在用的异常测量核心算法
本文按照孔再华老师在〖Deeplus直播第213期〗线上分享讲演内容整理而成。
孔再华 中国民生银行信息科技部数据库专家
今天我要分享的内容,有这样几个方面,首先讨论在数据库运维中存在哪些疼点,其次是我们为何要做智能运维,智能运维是哪些,我们在民生做得怎么样。然后会大约谈谈智能运维中的智能算法,最后是案例分享,也就是我们上了这套智能运维系统后究竟有哪些疗效,在使用过程中帮助我们达成了什么样的目标。
一、运维疼点
首先说说运维的疼点。我是农行的从业者,我们行内对数据库运维的要求,我总结为两点。一点是农行里对数据库运维的要求是特别高的,我们自己农行内部有个“双十”红线的要求,就是说数据库假若出现问题,那么须要DBA在非常种内剖析问题,十分钟解决问题。如果在非常种内没有剖析完成,那么先暂停剖析,救急的工作一定要开始做,争取在十分钟内把救急的工作做好。所以我们平常在运维过程中时间要求还是很紧张的。尤其是没搞清楚缘由的情况下,救急的操作可能最终没有解决问题。
另外一点是我们在运维过程中,会形成好多有价值的数据,我们对于机房所有的产品,无论是系统、中间件、数据库就会监控好多东西。即便是这样,我们如今监控的数据还是比较片面的,不是说没有更详尽的运维数据,而是我们没有办法把这种把数据用上去,现在我们只是人工选购了一些比较核心的指标,做了一些监控告警。
首先说说“双十”红线。如果数据库遇见bug,性能不好的SQL,我们大约会从运维系统的交易响应率,数据库的一些告警中晓得现今数据库运行平缓或则出现故障。这时候我们要赶快去搜集数据,查看日志,分析当前遇见问题是哪些。
如果我们是太有经验的DBA,那我们可能会基于现有的数据和现象,能够晓得说可能命中了个什么样的问题,如果曾经有相关经验的话可能能够很快解决。但若果说我遇见这个问题是个新问题,那之前那个解决方法我可能就做不到。
做不到的情况下,就只能做应急处理,把数据库的应用杀一杀,重启一下数据集,能如何做就如何做,通过所谓万能的重启大法,先把问题试着解决,后面再复盘,再把数据上收,发送给对应的数据库厂商来帮我们剖析问题。
这可能就是DBA平常的工作,采集数据,分析问题,应急处理,问题复盘。但是在这个过程中会有很多缺乏的地方,比如一开始搜集的东西不够多,就会造成问题复盘的时侯很难再现,这块虽然有好多疼点。
引申来说,除了我们现有对故障的处理的疼点,还有问题就是我们如今领到这种数据是不是没有哪些用?比说我们从数据库这一层面可以搜集成百上千个指标,那这种指标都是很奇怪的指标,你要是不查资料你根本不知道这个指标是干嘛的。对我来讲也一样, 我当然做数据库运维有很长时间了,指标也不是全部都清楚,我遇见后还是要去查一查看一看。
那这么多指标,它们都是有自己真实的含意的,大家不用上去的话是真浪费。如果我们可以做到把所有的指标管理上去,而不仅仅只是管理我们关心的那十几个重要的指标,那我们对数据库的洞察力会更强。
更进一步,如果我早已领到这种数据了,那数据和数据之间是不是存在好多的关系呢?比如说我们常常有这样一个需求,我们遇见一个问题,说那个东西不正常,你知不知道是哪些东西导致的不正常呢?会不会是其他的哪些事情?
我们平常在运维中剖析告警时,总是想办法去找跟它相关的这些指标,或者是诱因。这个相关性是可以从历史数据中找到的,如果我们早已把这个东西挖掘挖掘,并且产生一定的知识库,那真的遇见问题的时侯,我们基于这个知识库立即才能发觉是哪些情况。所以我们要挖掘运维数据的关系,并且借助上去。
再继续下去,我们不仅仅是管理了所有的指标,还理清楚了这种指标之间的关系,下一步就要凝聚彰显。比方说我这么多指标,密密麻麻上千个,到处发生异常对我来说没哪些意义,我想晓得整个行上面几百到上千个数据库,运行得怎么样,那我怎么样去观察它们?
那这个时侯就须要这样一个全局的视图,相当于说我须要数据库的运行状态通过一些有价值的数据指标综合上去,描绘出一个数据库的画像,这样才能从好多数据库运维中立即挑下来说什么数据库运行的状态是属于哪一种类型中,也就是把握住这个数据库的运行特性。
然后我们总结了几种类型,描述这个数据库太忙,它是一个事务性集中的数据库,它平常的业务量大而且数据量不多,它的io的承载能力或则各方面的属于中等。这就是一个数据库的画像,这个东西是我下一步会做的事情。
二、智能运维
其实说了这么多,从我自己的理解来讲,智能运维不是靠人为定义什么规则去开掘指标的关系,去看指标的含意,而是说我通过智能算法把指标采集起来,再把它们给训练和管理,然后智能算法自己从指标里挖关系,把关系提炼上去,最后通过智能算法把核心的指标挑下来,它们能展示我们自己想要的东西。
那做这件事情就是为了节约DBA的人力,因为我是个DBA,如果要自己手工做这些事,我相信是不可能发生的。但是自从机器学习比较流行以后,我也是见到了机器学习在数据剖析上的各类能力,所以我认为数据库这个层面,再加上机器学习,互相结合能激发下来火花,完成一些我们之前做不到的事情。
为了做这个智能运维,我们首先要对智能运维平台进行构思,比如说我这个平台究竟要做哪些事情,它要监管一些什么样的指标,我这上面有什么估算的内容,这些内容我们应当如何去依托现有的构架去实现,还有大数据量的挖掘和处理。
这里我大约提了几个比较重要的点,比如容器化。因为我认为现今云化容器化比较流行,我的估算节点是无状态的,通过容器化的伸缩,很快完成我的目标。事实上也确实是这样,智能运维到如今,监管的对象越来越多,内容越来越扩充,数据量越来越大,训练和实时处理的要求越来越高。自从用了容器化,把我的平台扔进去,我要扩充这方面的性能就显得比较简单。
然后关于机器学习的语言选择。其实也没有其他哪些好选的,python是现今最流行的机器学习语言,比较通用,算法包比较多,接口多。我自己作为初学者,来看应当用哪些平台时,python能解决好多开发上的工作,我能很快找到我想要的算法包,很快去把我想要的模型弄下来,研究它的疗效。所以我最终还是选择python,没有选其他高性能的语言,毕竟我那边开发能力资源有限,没有办法去砸很多人把python里的一些算法转化为java、c++高性能语言。
选了python以后,也是要在python里找对应的处理框架,最终找的框架帮助我在容器化里做动态的扩充。系统里有好多的高性能实时运算的工作,以前我们在监控的数据,一天的时间有12个亿多,所以你想想每秒里也有一两万的的样子,我要把那些东西全部实时的处理完似乎很困难的,我只能通过分布式框架纵向扩充的方法来解决。
最后一个是对象储存,这个是我计划用上去的,我们做python机器学习时,还须要一些地方储存我们的模型,那对象存储和容器化一结合,就解决了整个前前端的过程,解决了容器化无状态的需求。
下面会具体讲,我那边究竟做了些什么样的智能运维场景,第一个是异常测量,这个是我们在做智能运维过程中最先想要做的事情,如何把所有的指标进行机器学习的异常检查,而不是基于人为定义规则。
第二个比较核心的场景是根因剖析,如何在我测量到异常的情况下才能找到sql是哪些,是那个业务跑过来的。我晓得它跑的是哪些东西。不仅这么我还要去剖析sql为何这个时侯跟先前是否不一样,到底触发了个什么样的问题。
最后是做了个智能场景,其实是因为我异常测量的指标太多了,产生的异常也好多,大家对于这种指标也不了解,从我那边来讲,我会把这种指标,尤其是相关性比较强的指标聚合在一起,然后剖析它们在过往的过程中发生了哪些事情,那我把这个事情描述上去,把场景描述上去,我未来的异常测量都会通过场景的方法来进行告警。告诉你们说我用了什么样的场景,虽然说如今是测量到许多指标的异常,这些指标的异常都是说明同一个场景,这个场景是哪些,有什么样的解决办法。
首先看异常检查。异常检查我从四点描述,第一是对象,我异常测量的对象是哪些,举个反例,我们如今用数据库,我异常测量的对象是数据库还是sql,那当然挺好剖析。如果我们对一个数据库检测到了,我肯定希望检查全局的指标,如果检查到sql这个级别,sql的对象是不定的,有的时候有有的时侯没有,有的时侯换一个sql进来。所以这就不太好检查。
总体来说,光从数据库全局的指标来说,已经是一个很大的对象,比如说我在做DB2的全局指标的时侯,大概监控了四百个指标,然后做MySQL的全局指标的时侯,大概是三百多个指标,所以这个量还蛮大的,一个系统就这么多,然后每位机器每位系统都有这么多数据送过来,这个量还是很庞大的。
在确定好了我们要监控的对象以后,下一步要选购什么样的算法。在选购算法的时侯,其实也很简单,因为我们人力有限,所以不能挑有监督的算法,所以象那个分类算法,或者回归算法都不太适宜我们。我们适宜从无监督学习算法上面选购对我们有帮助的,后面会介绍一些算法。
到底是使用时间序列算法呢,还是其他算法。这个问题我也考虑了好久,因为选时间序列算法它面临两个问题,第一个问题是时间序列算法会导致检查出的异常点更多,因为它会把整个指标基于时间来剖析,而且我的训练数据也须要向前推,需要更久的历史数据。第二个问题是我用时间算法的话,计算量要比普通算法更高一些,对于我们原本要做太大量的学习指标的期望,是偏颇的,所以一开始就舍弃了时间序列算法。
前面谈算法的时侯提到了最关心的性能,性能主要收录两个方面,一方面是这么多的系统,这么多指标,一个系统400个指标,有400个系统,那就是16万训练对象,我要用多少资源训练能够完成呢。因此我对性能有很高的要求,我们在做整个算法的开发过程中,最关注的就是性能,一开始性能比较差,我们使用的原有的算法包里的东西,后来我们决定把算法的思想抽下来,然后把原先的算法包革除掉,只用我们的思想自己做算法,去求阀值的区间。
另一方面是实时处理的性能,同样这么多监控指标,每分钟采集一次,时时刻刻往这里怼,我需要解决。最后才是展示,最简单的,展示整个指标的发展曲线是最基本的要素,在前面我们还须要做到我这么多指标如何分层展示,让我有概念,其次昨天说的场景告警,怎么样能够把场景展示下来。
大概给你们谈谈我做智能检查的流程,首先我们第一步是从数据库上面获取全局的快照,快照上面主要是含指标的数据,不能说采了就往库上面存,还是要把它异步化,中间用了kafka做流处理,从kafka获取数据后,我的实时处理会对当时的快照和之前的快照做差值,把我们指标在快照间形成的数据估算下来,然后这部份数据会被我当作原创数据扔到数据库里,那定期会对数据库里的数据进行训练,历史数据,保存异常模型。原先我们保存的是模型,现在保存预值,就是由于性能问题以及对象储存的问题。
根据这个测量模型,加上上面的流处理接过来的指标,进行实时的异常检查,会最终在通过告警的形式或则电邮提醒用户,那从我的后面页面一样能看到总的异常变化量,在上面的每位指标,指标变化的情况。还会基于根因剖析把指标对应的sql,影响最大的排序,列下来,分析对应的sql情况。
我们作为专业的DBA,尤其是采集了这么多专业的性能数据,sql的详情页面,也基本上能够晓得sql出了哪些问题。
做异常测量的时侯,肯定选无监督学习,人工无法标明异常。然后在做异常检查过程中须要多用几种算法,因为每种算法思路不太一样,它的最终的疗效不太一样。结合几种算法以后,结果会更准确。最后能单并发十分钟训练400+指标模型。
下面关于根因剖析,根因剖析主要做的事情,一种是核心指标,cpu的消耗和总的执行时间是核心指标,一种是异常指标,当前页面上曝出的异常指标,这些指标无论是那个,我点击那些指标,然后查看我这些sql对它的贡献度,然后按照贡献度把sql找下来,在sql生成详尽的剖析报表。最终达到说我从发觉异常到找到问题sql,并且基于提示的sql指标能定位sql的问题是哪些。
问题根因模型,从监控里看见等待时间比较长,我会去看下什么sql占的等待时间比较高,那找到这种sql以后,我回家看单独的sql它历史的执行情况,能看到有些低点,在低点上面这个时刻它的时间分布是如何的,右边这个饼图讲执行时间的分布,分布上面会听到说,磁盘上面读或写的时间比较多,这种一般会说明问题,问题还须要剖析就不继续说了。
在上面两个做完的基础上,做了前面这个智能场景。第一智能场景是属于异常指标的凝聚,我把我时常发生的指标凝聚在一起,告诉他说的这是一个哪些场景。第二我给你除了报了命中这个场景,我还基于当时已然发生问题的指标,将它所关联的sql进行排序,告诉你命中这个场景,很大可能是这个sql引起的。这就是我要做的事情。
当然做完这种事情过后,从展示、告警各方面我们会有很多可以做的东西。比如我做了个大屏展示,也做了系统排名,命中的场景,系统上面能看到异常这样,现在异常量比较多,过去一个小时有多少个指标发生异常了,异常越多的一般是数据库当前运行状况变化比较大的系统,我肯定会关注异常比较多的系统,从我自己是个dba,从管理所有数据库的角度来看的。作为应用人员来讲,他须要关心的只是自己的系统。比如说我是个emu系统的负责人,我只须要看我emu系统的数据库,它所命中的是哪些场景。而我是个dba,我会挑异常量比较多的系统来看前面命中的异常场景。
针对DB2我早已做了28个异常场景,里面有日志写盘、回滚异常,锁异常,这些都挺好理解,所以从不太好理解的指标我们凝聚成一个挺好理解的智能场景,那我们就把这件事情做上去了。
日志写盘异常的反例:
LOG_DISK_WAITS_TOTALLOG_DISK_WAIT_TIMETOTAL_COMMIT_PROC_TIMETOTAL_commit_TIME
比如说这四个指标一般一起发生的,或者两两发生,都是为了说明同一个问题,日志写盘时间慢了还是怎么样,我那边会解释说是什么样的场景,可能须要再去剖析哪些东西,这相当于我最终给用户提供下来的解释。
在上面这个基础上我还做了个一键智能剖析,就像我们刚刚见到系统有26个异常,作为一个非DBA,或者只是个应用负责人,那你就须要我这边开发一键剖析按键,只要点这个按键,它就把当前所有指标基于异常场景剖析,告诉你说你的关联sql是哪些,这就是给普通用户使用的。
对DBA来讲,我希望大家细致些,仔细看完上面的指标,比方说第一个日志写盘的场景,里面有个哪些log_disk_wait,两两一块出现是相关性很高的指标,你看见以后呢,作为DBA来说会看log_disk_wait是个哪些含意,怎么回事。普通用户只须要看异常的剖析,解决的方案就可以了。
三、算法推荐
下面介绍一些在做智能运维过程中采用的算法。
首先谈异常检查算法,最简单的就是3σ原则,这种原则虽然是我们觉得,指标的数据会存在一定分布机率,假设它是符合正态分布的。事实上是不是这样呢?其实不是完全这样的,因为一个指标反馈的事情不一定是一个行为造成的,每个行为都存在自己的正态分布,合到一起后,指标数据由于遭到各自的影响,正态分布就不好说了。不管怎么说,作为最基础的算法,我们还是要讲讲这个3σ。
这个算法是假设这个指标符合均值和标准差的分布,如果超过三倍标准差的话,分布的机率就是0.003%左右了。通常来说,整个数据的集合上面,千分之三外边是属于不太容易发生的,所以3σ作为最普通的算法你们可以了解一下。
这个算法挺好,叫孤立森林,孤立森林的思路很简单,数据排好了以后,我通过建立孤立树的方法去来孤立样本,如果我在捅了无数次,能将样本最终孤立下来,很快并多次被孤立下来的样本,分布式应当是比较负疚的,所以它可能就是个异常点。
我第一步在整个数据里捅一刀,之后左右分,大于它的和大于它的,小于它的上面再随便捅,大于它的上面也随便菜刀,一层层往下捅,控制下捅的次数。10次或则100次,这是算法里的超参数,之后我们会发觉有些部份数据量还超过多少个,有些可能捅了一两个,那个地方数据量就剩一两个,没法再捅了。所以多次很快就无法下刀的树,就是异常点,这就是算法的核心思想。
通过这个算法,砍树行为,我虽然连正常数据标准化都不需要做了,因为我捅的时侯,按照最大最小值中间随机捅一刀,无所谓是1到100还是0到1,好处是不需要对数据进行预处理,并且算法支持非单一指标的测量。
后面讲个很重要的dbscan算法。这个算法是我做异常测量的核心算法,dbscan是无监督的聚类算法。看这个图右下角,Dbscan将数据分为三类,除了那些分类的数据外,还有边边角角的点不属于任何一类,因为距得很远了。从这个思路来讲,因为定义好密度后,这个点落在圈上面,我的密度足够,我的点是正常的一类点,那我认为ok,如果恰好在边上,属于临界点,也还ok,也还挺紧靠正常点。画的圈上面,数据点够不上这个密度,也达不到更其他点在一起,就是异常点。
结合三种算法后,做了集成疗效,第一个是孤立森林,第二个是dbscan,分为红色和白色两类,游离在其他地方就是异常点,第三个是3σ正态分布,很大量都是异常点,对我来说不太能接受,最后集成三种算法,如图右下角,形成最终检测出的异常点。
挖掘数据相关性,第一个是最常用皮尔逊相关系数,根据公式做数据标准化处理后,结果就是想要的相关系数。结果是1的表示正相关,同起同落,-1就是负相关,你高我就低此类,不管是哪种都是能说明相互之间是有关系,然后聚在一起,人为去看它的涵义。
下一个是apriori,这种算法比相关性更不好理解和更不好处理点。因为它是基于机率的算法,不是基于离散型数据的。指标值上上下下是离散型的,那用这个算就无法做。但我们有异常检查能打标签呀,打完标签以后的标签数据给这个算法用就再合适不过了。
最后基于0和1的标签关系,计算下这种指标是不是同时发生异常,发生异常的比列怎么样,我就可以得到,他们相关性的结果,它们核心的支持度、置信度、提升度在这里可以去看一下,跟机率相关的。