本文做者:AIOps智能运维程序员
做者简介算法
周伟 百度云高级研发工程师缓存
负责百度云智能运维(Noah)告警通告系统的设计和研发,在大规模分布式系统、运维监控、精准报警等方面具备普遍的实践经验。架构
干货概览框架
本文提到的异常检测(Anomaly Detection)特指在运维领域中对时序数据的异常检测,目的是为了发现时序数据中状态的变化。运维
在咱们看来,异常检测通常可分为两类:简单异常检测和复杂异常检测机器学习
简单异常检测:通常指恒定阈值检测,好比判断可用性指标是否小于99.99%,若是小于则检测结果为异常,不然检测结果为正常。简单恒定阈值检测通常适用于可用性、资源利用率等监控指标。分布式
复杂异常检测:对于收入、错误率、流量等业务监控指标,须要检测天/周/月/年等环比变化或者突增突降等状态变化,这类业务监控指标的维度特征较多(好比地域、运营商等),特征变化也比较快(例如电商按期搞活动,流量瞬间涨起来,干扰正常的异常检测)。恒定阈值检测每每没法检测到这类业务监控指标的状态变动,因此还须要复杂异常检测算法来检测业务监控指标的异常。为了发现监控指标的状态变化,复杂异常检测每每会采用机器学习、深度学习等比较复杂的技术。函数
和简单异常检测相比,复杂异常检测对落地流程和异常检测的运行平台提出了更高的要求。学习
落地复杂异常检测的阻塞点
为了支持简单异常检测,异常检测的运行平台只须要可以支持用户添加自定义报警判断规则便可。好比,对于上面提到的可用性指标,用户能够在系统中将报警判断规则配置为表达式“SLI < 99.99%”,而后等着接收报警就能够了。
然而对高级异常检测算法,算法从研发到上线,通常须要包括如下三步:
线下编写算法脚本(通常是Matlab或Python脚本),并根据历史数据,离线训练算法所依赖的参数,经过用历史Case进行回溯验证效果。在这个过程当中,算法工程师须要反复调整算法参数,直到准确率和召回率都达到目标为止。
将算法脚本改写成线上代码(通常是C++、JAVA语言等编译型语言)。这是由于线下编写的算法代码通常和线上运行代码使用不一样语言开发,线下实验算法代码更侧重研发效率,须要快速迭代和测试,而线上运行代码更侧重运行效率,高效稳定运行。
最后将改写后的算法代码生效到线上,并观察其运行稳定性和资源消耗状况,及时调整线上资源分配状况。
以上流程在实践的过程当中存在若干阻塞点,致使复杂算法落地时间长,算法迭代效率低:
线下实验的过程当中,历史数据、历史Case、不一样实验所使用的算法、参数和效果全靠人工管理,经常出现指标数据不全,历史Case不全,实验过程兜圈子的状况。
线下代码和线上代码开发语言不同,代码移植须要消耗比较多的时间,经常不能保证线上代码和线下代码的效果彻底一致。
一些复杂算法对资源的消耗很大,贸然上线会影响监控系统部分或总体的稳定性。
落地复杂异常检测的需求
上述阻塞点很容易致使算法迭代速度跟不上指标变化速度的状况,最终限制了检测效果的提高。因此,为了保证算法的顺利落地,咱们须要提供一个新的异常检测支持方案,知足如下的需求:
须要一个方便算法快速迭代和算法验证的环境,用于在线下调试算法脚本,并对历史Case回溯,保证算法的普适性。
须要能弥合线下脚本和线上代码鸿沟的机制,尽快将算法生效到线上,能快速验证算法代码的真实效果,不然线下实验脚本和线上生效代码迁移成本过高,费事费力费程序员。
须要评估线上代码的资源消耗和稳定性状况。由于复杂异常判断算法,其资源需求差别性特别大,好比有的会采用深度学习等很是耗CPU/GPU的算法,而有的仅仅是简单公式计算。另外,这类算法开发迭代特别快,算法代码很容易引入Bug,因此须要在不影响其余线上算法运行的同时,采用线上真实流量验证算法稳定性。
须要分离算法代码和算法参数,并支持算法参数的独立更新。由于算法通过快速迭代后,会逐渐稳定下来,可是算法的参数是对历史数据的特征表达,因此算法所依赖的参数须要周期性更新,保障算法达到最优效果。
落地方案
为了解决上述问题和需求,咱们推出了异常检测运行平台。基于运行平台,算法工程师能够用脚本语言(当前支持Python脚本语言)线下编写异常检测算法,并在线下回溯历史Case,当策略调试完毕后,能够直接将Python算法脚本生效到到线上。同时,还支持算法参数的独立更新,大大加快算法的生效速度。
异常检测运行平台包括三个环境:离线环境、在线环境、近线环境,下面详细介绍。
1 离线环境
离线环境会提供如图1所示的策略开发框架,异常开发框架提供了Python运行环境和经常使用的Python库,基于开发框架,算法工程师采用一致的抽象接口编写算法代码,这样能够保证在线下开发的算法代码能够直接放到线上环境运行,从而弥合线下脚本和线上代码鸿沟。为了回溯Case,开发框架还提供了历史时序数据组件、异常判断评价组件(支持准确率、召回率、F1 Score等评价指标)。因为复杂异常检测算法不像恒定阈值算法能够根据数据直观看出判断结果,复杂异常检测算法每每须要运行并输出异常判断结果(能图形化展现更好),才能评估算法效果,因此开发框架提供了图形组件,能够图形化展现异常检测结果。
图1 策略开发框架
图2展现了算法开发接口,其中包括四个标准接口:
load_model函数负责加载算法参数;
get_data函数负责加载指定时间段的历史时序数据;
initialize函数负责在算法正式运行前进行初始化,好比加载算法参数、申请内存等等;
detect函数负责对时序数据点进行异常检测,并返回异常检测结果(正常或异常)。
图2 用于高级异常检测的抽象接口
2 在线环境
算法工程师在线下环境基于开发框架开发完策略算法后,能够将算法发布到在线环境。在线环境提供了跟策略开发框架一致接口的策略运行时环境。策略运行时环境会接收上游发送的时序数据,并驱动Python算法脚本周期性运行,同时将产生的异常判断结果发送到下游,用于报警通告。
图3 在线环境架构
在线环境的架构图如图3所示,在线环境主要包括如下三个模块:
任务分发模块:负责管理运维人员提交的高级异常检测算法配置,并将每一个算法配置组装成任务,分配给任务运行模块。
数据调度模块:数据调度模块周期性从任务管理模块同步任务的分配信息,根据任务分配信息,将每一个任务所需的数据调度给相应的任务运行模块,同时将数据也Copy一份,写入到时序数据缓存中。
任务运行模块:任务运行模块周期性从任务分发模块拉取分配到的任务,并为每一个任务启动一个策略运行时环境。策略运行时环境支持跟开发框架相同的接口,因此能够直接驱动基于开发框架开发的算法代码的运行。策略运行环境刚启动的时候,会调用intialize函数,进行初始化操做,而后策略运行环境不断接收数据调度模块调度过来的数据,并驱动调用detect函数,detect函数会对接收到的数据进行判断,并返回判断结果(正常或异常),运行时环境收到判断结果后,将其发送到下游,用于报警发送。有时算法在刚启动或运行的时候,须要拉取近期的时序数据,这时经过get_data函数从时序数据缓存中获取便可。另外,任务运行时环境还会周期性检测算法依赖的参数是否有变动,若是算法参数被更新了,则会调用load_model函数从新加载配置。
3 近线环境
在线下环境编写算法代码,若是直接贸然上线到在线环境,每每会存在不少问题,因此策略算法在离线环境验证可用后,首先会放到近线环境运行起来,近线环境和线上环境的架构和功能其实没有本质差异,只是用途不一样而已。近线环境的目的,一方面是为了用线上真实流量数据来验证算法的资源消耗,以发现算法运行的真实资源需求,只是不真正发送告警而已;另外一方面,是为了验证算法的稳定性,好比是否有内存泄漏、是否有崩掉、是否有错误日志等等。若是发现有问题,算法工程师能够快速调整并从新部署到近线环境进行验证。
总 结
本文主要介绍了异常检测的相关背景、应用场景和需求分析,而后咱们给出了百度云的高级异常检测算法快速落地方案——异常检测运行平台。目前运行在这套异常检测运行平台上的高级算法超过20个,天天处理近千万监控指标的异常判断。算法的线上迭代周期从周级别减小到天或小时级别,很好地支撑了业务方对不一样高级异常检测的需求。另外,咱们还将平台开放给业务运维人员使用,由业务运维人员研发的异常检测算法能够有效引入业务线人员的专家经验。
关于高级异常检测算法的落地,有任何想法和疑问,欢迎留言一块儿交流。