网易游戏AIOps实践:年度异常检测优化策略与平台建设理念。原定义为AlgorithmITOperations,是指通过机器学习、数据仓库、大数据等技术手段,将人工智能应用于运维领域,基于数据(日志、日志、监控、应用等)运维产生的。将制定最佳运维策略,随着技术的成熟,最终将走向无人化运维。一、AIOps路线规划1、AIOps能力阶段非一日之寒。根据此前发布的企业级AIOps实施白皮书,AIOps的发展主要有以下五个阶段。这在我们目前的实践过程中确实得到了验证。在尝试应用AI能力之初,并没有更成熟的单点应用。具备单场景AI运维能力,可初步形成内部使用的学习软件。具有多个单场景AI运维模块串联的流程化AI运维能力,可以对外提供可靠的运维AI学习软件。主要运维场景实现了基于流程的免干预AI运维能力,可以对外提供可靠的AIOps服务。以核心AI为核心,在成本、质量、效率三方面从容调整,满足不同业务生命周期的不同指标需求,实现多目标或按需优化下的优化。网易游戏智能运维团队从2018年开始算法研究和具体实施场景选择,随后在在线用户数、异常检测、日志异常检测等方面尝试单点应用突破,取得了显著成果。目前,通过串联各个维度的运维信息和告警信息,实现入村后故障发现和故障自愈的目的,从而实现多维度的流程化AI运维能力。单场景AI运维模块串联。这里的学习软件指的是AI运维组件,最初是南京大学的周志华老师创建的。它指的是模型+协议,具有可复用、演进和理解的特点。AIOpsPhase2,人员结构与DevOps相比,AIOps的人员结构肯定发生了一些变化。最显着的变化是增加了算法工程师的角色。有些团队往往被称为算法开发研发工程师,即兼具算法和平台开发能力的工程师。当然,如果一个算法工程师能够具备很好的工程能力,这对于整个团队的发展肯定会有积极的影响。但是不好意思,要求一个团队里的每个算法工程师都具备很好的工程能力其实还是挺难的,尤其是在招人的时候,你会发现算法和工程在一定程度上还是分开的。因此,我们团队的配置更多的是以下三个角色:运维工程师,或者说我们的用户,负责向算法工程师提供具体的业务场景和需求,挖掘潜在的智能场景,为平台提供支持。研发项目提供平台开发的场景需求。此外,还有平台研发工程师和算法工程师。一个主要负责工程和平台建设。他懂一点算法,但他的主要职责是更多的工程开发。算法工程师则专注于算法对应业务的研发和优化。这种结构也是为了技术行业的专业化。经过实际合作,这种合作方式大大提高了业务开发的效率,但也存在一定的技术盲点。3.业务领域1)时序异常检测时序数据是按时间顺序排列、随时间变化、相互关联的数据序列。由于运维场景的特殊性,运维数据天生就与时间序列密切相关。AIOps提供的时序智能分析能力,是通过研究历史数据的变化趋势和内在属性,实现无人参与的时序预测、异常数据监控等智能分析功能。2)故障定位和根因分析随着微服务的发展,业务组网越来越复杂,问题定界和定位分析变得尤为困难。故障识别与诊断是运维场景智能分析的核心部分。AIOps提供的故障识别和根因定位能力,利用数据挖掘,结合故障数据和人工经验,自动提取故障特征,进行故障定位。3)文本处理分析文本处理有广阔的空间。AIOps提供广泛的文本处理和分析能力,涵盖信息抽取、语义分析、智能搜索、对话系统等领域,并提供可直接应用于产品策略的NLP技术能力。4)聚类与相似性分析将物理或抽象对象的集合划分为由相似对象组成的多个类的过程称为聚类。聚类是根据某些相似性进行抽象的过程。AIOps提供的聚类和相似性分析服务可以使用有监督或无监督算法,结合统计特征,对给定格式的数据进行相似性聚类,从而大大降低数据识别和处理的成本。2.异常检测1.问题传统的静态阈值目前难以适应不断变化的业务场景。阈值过高会漏报告警,阈值过低会引发告警风暴。时序指标的异常检测不同于传统的静态阈值,用户无需手动配置。AIOps通过机器学习算法结合人工标注结果,自动学习阈值,自动调整参数,提高告警的准确率和召回率。异常检测可以更好地适应业务的多样化需求,覆盖更多的异常类型。2.适用场景1)异常阈值难以定义。很难明确定义正常和异常数据,也没有明显的阈值边界。不同的时间段有不同的阈值。有些数据的异常值突变没有达到预定义的阈值。需要识别的异常是历史数据具有一定表现模式的异常,不能设置阈值进行检测。2)人工配置成本高。不同的曲线配置有不同的阈值。当曲线较多时,手动配置的成本非常高。随着业务的变化,预定义的阈值也需要随之变化,运维成本高。本身就含有噪声,很难区分噪声和异常数据,需要大量的人力去检测。对于异常检测,其实网上很多文档或者书籍都给出了一些常用的算法或者工具。我们也在这方面应用了这些算法或工具。当然,我们也做了很多相应的算法优化和调整。这里我给出我们团队在这方面的一些思考和策略。当模型上线时,我们选择统计+规则的无监督方案。主要优点是:无监督,无数据标注,成本统计+规则,可解释性强,模型预测时延低,受曲线时间粒度影响小3)异常毛刺异常毛刺是非周期性的KPI曲线在某一时刻突然出现的局部最大毛刺。如果仅仅通过KPI的大小来进行阈值判断,很多时候是无法准确发现异常值的,因为KPI值本身也可能存在一定的趋势。利用一阶差分可以有效去除趋势项,从而暴露异常。此外,SR算法对此类异常也有很好的检测效果。4)异常突升突降异常突升突降表现为KPI曲线出现异常突升或突降,且没有立即恢复,KPI值持续保持在异常值附近的异常。这是一个持续性的异常,很多业务,比如在线人数、CPU使用率等,都非常关注这种异常。可以通过异常值两端窗口内均值的偏移来识别此类异常。但是,由于KPI本身是有趋势和周期的,所以在正常点两端的窗口中也存在均值偏移。这时候可以使用STL对时间序列进行分解,然后计算残差部分的均值漂移,可以减少趋势项和季节性项带来的误报。此外,大的毛刺也会产生均值漂移,容易出现误报。因此,在计算窗口两端的均值之前,通过esd检验去除异常值,可以去除大毛刺对均值的影响,减少模型的误报。5)频率变化异常频率异常表现为连续的毛刺异常。此时曲线的震荡加剧,也属于连续异常。这种曲线虽然比较少见,但也是商家比较关心的异常类型。可以使用窗口内的一阶差分异常计数值来进行确定。3.异常判断方法在设计了各种检测模型后,需要根据模型的输出进行异常判断,从而判断当前点是否异常。对于瞬态异常和持续异常,需要采用不同的方法进行异常判断。1)分布法基于数据分布假设设定阈值,适用于瞬时异常的判断。我们使用3sigma和箱线图来判断瞬时异常。经过测试,他们对大部分曲线都有比较稳健的判断结果。2)业务计数阈值法根据业务需求设置计数阈值,适用于持续异常的判断。我们对连续异常设置一个计数阈值,如果异常计数超过阈值,就会发出告警。例如,在稳健回归中,统计实际曲线与预测曲线之间差异的次数;比如窗口内一阶差分的计数可以直接通过计数阈值来判断。此外,为了融合不同模型的输出,获得更稳健的判断结果,可以将分布法和业务计数阈值法通过线性转换转换为0到1之间的分数。此时可以通过对分数进行加权得到模型融合,如果融合分数超过0.5则为异常,在不同的曲线中都能保持较好的异常判断效果,同时也具有很强的鲁棒性。3、平台建设AIOps本身也是一种迭代开发的模式,我们在平台化的过程中也遇到了一些问题。首先,算法和工程之间的界限变得模糊。算法工程师希望专注于算法开发和调优,不想在工程上花费太多时间。此外,算法包与项目强耦合,算法的每一次优化和参数变更都需要项目的配合和发布。我们希望算法和工程能更好的解耦,既能满足算法快速迭代的需求,又能满足工程平台开发稳定性的要求。此外,我们还发现AIOps使用的数据可能是多种多样的。对于异常检测场景,基础指标数据、日志数据、模板数据都是不同的。延伸到故障定位可能还需要使用配置相关的数据,比如业务拓扑、网络拓扑的CMDB数据,甚至还要结合异常事件、变更事件等事件信息数据。1.系统架构设计基于以上问题和目标,我们设计了如图所示的五层系统架构。其核心目标是在保证高可用的同时,按需加载不同的算法,安排不同的检测流程,实现高可用。提供多种业务类型,统一管理。每个业务甚至流程都通过统一的平台进行隔离和调度。为了节约资源,动态调整算力,保证整个服务的运行效率。1)数据访问层最底层的数据访问层,负责实时采集各种监控指标、系统日志、业务日志和业务指标。对于系统和业务指标,可以通过我们监控团队自主研发的agent进行数据采集。一般在每个服务器初始化的时候都会自动安装和配置。2)数据层上述数据访问层采集的数据会写入HDFS进行持久化,该层还会负责对采集到的数据进行预处理、ETL、聚合等。为了提高性能和可用性,指标数据会根据冷热数据的不同,分别存储在TSDB和Redis中,我们检测中使用的历史数据就是从中获取的。3)在服务层,主要是对模型进行离线训练,训练好的模型上传到S3存储。当模型迭代或算法策略改变时,算法工程师可以独立完成整个链路的开发和测试。不需要平台工程师访问权限。由于模型是从平台框架中抽取出来的,可以独立配置和管理,进一步降低了算法和项目之间的耦合度。此外,当接入新的业务场景时,算法和工程师可以通过约定接口独立开发代码并上线。4)应用层不同于网络服务的应用层。这里更多指的是不同saas平台的功能应用。基础运维负责反映真实的指标波动,通过数据层聚合数据。目前,我们的监控团队已经实现了秒级监控的数据展示。该层也嵌入了AIOps平台,主要功能是通过实时流、任务调度等方式调用相应的模型对数据进行各种算法检测。5)展示层用于检测结果的展示,可以以单个事件或数据图的形式展示。2.检测流程设计这里主要介绍检测平台在应用层的内部实现思路。整体数据流如图所示。用户会在我们的运维入口创建相应的检测任务,并将配置同步到flink规则库进行存储。这个时候agent会收集相应的指标数据,并发送给flink进行预处理。配置数据的预过滤和预处理。处理后的数据也会经过一个算法整理模块。该模块主要是根据之前的用户配置和我们预设的匹配规则,在检测到的数据中加入一些安排、任务、策略相关的信息。这类信息决定了算法使用的模型、历史数据、特征等信息。然后根据这些信息动态加载模型,调用并输出结果。算法模型是对算法的抽象,模型可以通过注册上传的方式上传到S3存储。注册完成后,算法模型会生成相应的组件进行编排和训练。平台和组件通过定义算法、接口和输入输出类的唯一标识符进行交互。平台调度引擎会根据上述配置动态加载相应的算法模型进行检测和调度。具体检测架构的实现思路如图所示。首先,算法模型作为可插拔的算法包存在于服务中。每个算法包都有一个独立的线程资源,可以通过python类加载的方式按需下载和更新,实现算法模型的热部署。框架本身相当于一个调度管理工具,负责加载不同版本的算法,执行算法路由和策略计算。同时,我们设计了一套相关的编排和调度协议,将具体的参数配置和编排方式开放给工程师自己定义,进一步解耦算法与工程、业务与平台的关系。例如,一些业务场景往往需要使用历史数据。事实上,算法工程师并不关心历史数据的获取和预处理。此类操作一般由平台工程师处理。我们对平台内部的历史数据获取逻辑进行了抽象。具体业务数据的采集和存储由平台工程师根据业务需求编写。相应的输入输出,算法调用模块通过协议获取一些关键参数和配置,自动调用这些具体的类和方法取数据传递给模型进行检测。事实上,在历史数据的获取和处理过程中,历史数据的提取往往成为瓶颈。例如,该算法可能需要7到8天的历史数据作为输入。随着检测次数的增加,这会对TSDB造成巨大的压力,另外,计算历史特征可能需要的输入量也不一样。冷热数据,读写分离可以解决。我们的平台也为历史数据维护了一套内存存储,并通过pipeline增加了数据压缩。缓存历史数据的方法。同时将部分计算特征存储在内存中,减轻实时计算模块的压力。这是我们的抽象类图的实现。基础类提供存储、排列、更新等基本操作。由于平台开发工程师根据业务场景自行定义数据,将这些独立的功能组合起来,以满足各种业务。需要。在用户体验方面,我也做了一些改变。首先,异常标注的方式。我看到很多平台都是以事件和同比对比的形式展示的,因为我们已经有了报警平台的兄弟系统,而且实际使用后发现这种形式的单事件同比比较容易误导用户,所以我们使用grafna这样的大图来展示和标记异常。此外,用户反馈和标注非常重要,很大程度上决定了模型的调优,提高了算法的准确率。有时用户实际上很懒惰,往往会忽略标签。我们使用内部消息工具popo直接将检测结果和标注链接发给用户,培养用户标注的好习惯。4、智能故障管理随着游戏和系统架构的日益复杂,运维人员收到的告警信息也变得五花八门。面对故障时,五花八门的告警信息让运维人员难以理清逻辑,甚至忽视对方,无法第一时间解决核心问题。在与我们的程序和SRE沟通的过程中,我们发现他们在面对故障时主要有以下痛点:游戏结构越来越复杂,出现故障后排查环节相对较长。故障发生后,往往会触发多个告警,但这些告警比较分散,没有按照一定的规则进行分类和可视化。因此,在排查过程中需要人工对告警进行梳理和过滤。目前,故障定位依赖于人工经验,难以复用。众所周知,业务指标是最直观的故障响应方式,而日志记录则是记录应用程序运行状态的重要工具。我们希望在保留细节的情况下,通过聚类对上述广义告警信息进行汇总,使得告警发出后,结合指标、日志、跟踪、变化事件等信息,通过故障传播链进行关联,故障的最佳可能原因。业务指标是整个故障定位的触发源。我们选取了游戏SLO中的重要指标,按照群体维度进行分类。由于SLO业务指标有很多glitch,直接使用普通的glitch无监督模型会产生较多的误报。只有异常持续上升或下降一段时间,才算异常。因此,SLO异常检测模型采用上升异常检测。电梯异常检测主要由两个模型组成,一个是均值漂移模型,另一个是预测均值漂移模型,最终的结果会融合两个模型的输入和输出。1)meanshift模型计算给定量左右两侧的均值差。当差值大于或小于某个阈值时,认为存在异常升程。2)均值预测偏移模型首先分别对给定的左右两侧点数进行线性回归,预测左右两侧给定点数的值。然后把它和左右两边的真值做个差值。平均这些差异。当平均值大于或小于某个阈值时,认为存在异常提升。业务指标异常后,启动故障定位,启动机器指标异常检测和整理。通过对异常分数进行排序来获得异常最可能的根本原因。当业务指标异常时,在当前时间点向前推20分钟的时间间隔内对所有指标进行毛刺异常检测,并计算异常检测分数。异常检测分数乘以时间衰减系数作为根本原因分数,即异常发生越早,越有可能是根本原因。输出20分钟内rootcause评分的最大值作为该指标的rootcause评分,然后在机器名范围内排序。在只考虑单个rootcause的前提下,异常最多的机器就是rootcause机器,指标异常按照RootCauseScoreSort输出一个metricrootcauses列表。在对机器指标异常根因进行排序的同时,我们也会扫描相关的SaaS机器指标和告警信息,最后结合日志异常检测和分类,将根因结果展示给用户。Q&AQ1:智慧运维前期规划有哪些好的方向和规划建议?A1:首先,智能运维不是一朝一夕的过程,而是作为一个长期演进的系统存在的。它的基础仍然是运维自动化、数据采集、分析、监控等基础运维工具。前期规划需要解决的问题包括海量数据的存储、分析和处理,数据仓库的建设,基础监控的实践经验等,好的数据往往比模型更有价值。完成以上基础建设后,您可以与具体业务人员了解您最关心的SLO,并通过这方面进行异常检测建设。在模型选择上,虽然有监督标注的成本会很高,但有监督模型比无监督模型更容易满足业务需求,在后期的更新迭代中具有绝对优势。Q2:AIOps的基础一定是大量的历史监控数据。您如何设计数据收集规则和建模规则?A2:目前我们基本采用了prometheus的接入方式,并在此基础上搭建了数据采集中心。它的主要收集规则是基于收集器和适配器模式。用户通过收集器上传数据,适配器将数据重新组装后直接发送到对应的消息队列中存储。数据模型统一使用json标识,数据格式采用prometheus的数据格式。Q3:能否介绍一下日志采集规则?现在日志检测的思路是什么?A3:用户通过我们的自定义客户端定义相关的日志指标,自行采集数据。sdk单独启动一个进程定时读取内存中的数据,组装成日志格式,由我们的日志组收集。具体数据格式同上一个问题。对于容器日志的收集方式,一般采用以下几种方式:收集容器中的日志:容器进程自己写;代理收集。容器外部采集:dockerlogsapi和dockerlog-dr;日志收集代理;安装卷;自主研发代理。我们目前的日常异常检测算法主要依赖于日志智能分类算法。获取日志实时分类模板后,我们需要使用3sigma和boxplot根据各模板日志量的历史数据进行异常判断,从而发现异常模式并将相应的异常发送给用户通过警报。Q4:告警收敛有哪些思路,哪些效果比较好?A4:告警收敛有以下几种方式:基于预设规则收敛。比如A和B的告警来自同一个机器/模块,AB会被收敛合并。基于告警时间/告警次数的收敛。例如5分钟内的告警合并发送。以上两种都是策略类型,可以收敛一些告警,但是无法得到告警之间的关联。基于拓扑收敛。根据拓扑关联告警,达到收敛效果。可以得到告警之间的关联性,有助于故障排除。但是,通常很难获得拓扑。基于收敛的关联规则挖掘。根据历史告警信息,挖掘频繁同步的告警规则并合并。可以得到告警之间的关联,但仍然没有故障现场,具有一定的排查效果,不依赖于拓扑结构。构建告警知识图谱并进行收敛。理想化的方式效果最好。然而,这需要拓扑和历史数据的积累,以及专家知识,这是很难实现的。Q5:如何选择基于互联网电子商务应用监控的动态阈值算法?A5:主要分为有监督选择和无监督选择:有监督异常检测的方案可以先使用CNN+AutoEncoder模型对曲线进行分类,建立无监督模型采样发现异常样本,从而建立样本库。并使用基于经验选择的一系列特征作为监督模型的数据输入。最后,使用集成模型对数据进行训练,以保证模型的稳定性。无监督异常检测方案采用建立包括3-sigma、百分位数分布和箱线图等在内的综合模型,通过计算历史数据中特征的多重分布来判断特征当前异常的可能性,进而得出异常分数将不同特征计算出的特征按比例组合,并与根据经验设定的异常阈值进行比较,检测异常。
