业界根因定位实践

简介

调研一下工业界的方案,综合转载于:

百度:智能运维在百度日常业务监控中的探索

引言

随着互联网产品规模的爆发式增长,大型分布式系统的监控复杂性也日益显现。工程师们发现:监控遗漏导致宕机的黑天鹅现象频繁发生;出现故障时很难从海量监控指标中迅速找到故障根因;报警风暴极大地干扰了工程师定位问题的速度;故障恢复速度基本依赖于工程师的操作速度。由此,我们尝试建立一个智能运维监控系统,希望用智能化的手段去帮助工程师解决这些问题。

百度数据情况

随着百度各产品的蓬勃发展,百度的服务器数量也呈现出爆发式增长,最近5年增长了大概20倍的规模。与产品规模不断增长相对应地,运维人员每天会收到越来越多的监控报警,面对海量的运维指标,如何快速定位问题所发生的业务层面,达到精准化报警、快速解决问题的目标就成为运维监控常态化的需求。

百度监控系统数据规模,单以时间序列数据为例,不包含日志类数据。

  • 服务器指标数量:>1亿
  • 业务指标数量:>8千万
  • 数据增长速度:50TB/日

运维中面临的监控问题

当前,面对复杂的业务监控和问题诊断,运维人员想找到指标和事件之间的关联关系,进行因果关系推导,并最终定位故障,基本依靠人的经验来进行。但随着业务和监控规模的膨胀,运维也希望能够更加自动化、智能化地达成保证服务高可用性的目标,即快速的问题发现、分析定位或止损。

下面,我们可以从发现问题—分析问题—解决问题的思路出发,逐步给出递进的解决方案。

发现问题篇:异常自动检测

日常运维的业务指标数据会出现一些环比昨日的明显异常、持续偏离的明显问题和随着时间周期漂移的指标数据等问题,以前这些监控的配置基本靠工程师经验或持续的迭代修正,甚至纯人工排查。随着监控系统的发展,可以通过制定监控标准和自动化监控部署实现运维的标准化和自动化,最终的目标,是希望用智能化的方法彻底解决这个问题。

一般,在系统出现指标数据波动时,需要先判定是否确实为异常情况,确定异常后再实现精准报警。那么,怎么自动检测业务的异常指标,帮助运维工程师和开发工程师处理问题呢?

这里主要有两个策略,自动恒定阈值设定与动态阈值设定:

1.恒定阈值设定法

对于普通数据,运维人员在服务器端设定服务器应用指标超过某合理数值自动报警,并对服务器异常的波动状态进行报警。这个可使用一些标准的统计学方法去自动计算这个阈值,取代人工配置成本。

参考方式:

  • 基于历史数据统计
  • 假设正态分布
  • 3-sigma策略

2.动态阈值设定法

百度大多数业务数据的流量呈现很强的天周期特性,在某时刻出现数据波峰的骤降或波谷数据的骤增等变动情况时,恒定阈值法很难解决这类问题的精准异常判断。那么我们可以把上述方法衍变升级一下,采用动态时间窗口的阈值设定法来解决周期性数据的异常判断。

参考方式:

  • 多分布形式:将数据分段
  • 按天同期计算统计阈值
  • 分段3-sigma策略

3.恒定阈值和动态阈值的使用

针对以上两种阈值划分方式,异常检测系统如何知道应该对每组数据进行什么样的异常检测策略呢?这就需要一种方法提前对数据进行分类,可以采用一种可判断数据是否具有周期性趋势的分类器方式来解决。如果数据具有很强的周期性特征,建议使用动态阈值设定法;如果数据分析后没有周期性特征,那么使用恒定阈值就可以了。

另外,我们还会遇到这种特殊的情况,数据会随时间出现漂移。比如某产品流量,会按照工作日、周末、传统长假等时间呈现出不同的数据特征,产生阶段性变化。这个时候要进行异常检测,就不仅要考虑数据的普通周期性,还要考虑季节性和趋势性的变化。监控系统可通过对日常数据进行分析,采用三次指数平滑等方法,对数据本身的趋势性进行学习。

当然,上述方法都是基于从历史数据进行学习分析从而进行异常检测的,如果缺少历史数据,那么对于这些指标,基于历史数据进行同环比分析的意义就不大,核心就转化为检测数据有没有突升和突降异常。可采用类似于局部平滑的方法查看真实数据与局部平滑后数据有没有大的出入,如果差距较大,可判断为有大的突升和突降,可以标识数据异常。

参考方式:

  • 局部平滑法
  • 速度法

经过经验的积累,对于核心产品的流量变动,即使波动不大,监控系统也可以做到灵敏且精准的指标监控,能够快速发现异常情况。当然,全自动的异常检测系统难免会出现误报、漏报等情况,这就要求异常检测系统需要支持工程师的标注与反馈,百度监控系统的自学习能力可以根据工程师的需求进行动态调整,可同时支持人为调整和系统自动参数学习调整,系统可自动根据工程师的标注或报警量的多少,进行参数训练,把异常检测参数调整到合理的范围。

综合上述方法,百度智能监控系统中的自动异常检测最终形成两种状态的结合:离线状态和在线状态,离线部分可根据历史数据进行分类学习、参数训练,而在线部分能够进行最终的异常检测和报警。

具体的组成如图所示:

发现问题篇:精准报警

监控系统仅仅发现了问题还不够,由于指标数量太过繁杂,为了起到辅助工程师快速解决问题的效果,还需要做到精准化报警。百度的精准报警主要分成两个层面,一个是单个指标的报警是否足够精准;这里需要考虑两个问题,一是是否每次异常都应该报警?需要容忍系统毛刺的存在;二是异常过滤,把离散的异常点转化为异常事件或状态,找到指标和事件的关联关系。

在单一指标的报警足够精准的基础上,另一个是把不同指标的报警结合起来做到足够精准。如何把多个指标的报警综合起来呢?简单策略是固定时间窗口来报警,时间相近的报警可进行一定的合并,只要将首先出现的指标报警送达给到运维人员即可。从整个监控策略来看,把报警综合起来,同类的报警进行合并来报给运维人员。复杂一些的策略是关联挖掘,把历史上产生的运维报警和事件关联起来报警,同时,某些报警经常频繁地一起出现,可以认为这是同一个报警,不再单独分别进行报警。

采用的具体策略有:

  1. 报警合并简单策略

    • 固定时间窗口

    • 相同监控策略

    • 相同监控对象  

  2. 报警合并复杂策略

    • 关联挖掘

    • 合并置信度较高的频繁项集

  3. 报警依赖

    • 策略依赖

    • 异常依赖

分析问题篇:关联分析

监控系统不仅需要帮助工程师发现问题,同时还需要通过建立关联分析,进行辅助问题定位,甚至迅速找到相关的指标或影响。那么,如何为复杂多样的运维数据建立关联呢?

产品服务层级的关联关系图:

运维工程师可以把一些基础的关联关系配置到监控系统中,可以让监控系统明白一些常态化的运维指标与其它指标是否存在关联,比如多个模块的异常是否存在关联、服务器升级或者部署产生问题是否与数据中心或交换机异常有关等。

具体的实现策略有:

  1. 关联挖掘

    • 事件和事件间的关联

      • 频繁项集挖掘

      • 所有运维事件

    • 事件和时序间的关联

      • 指标异常经常与部署升级事件相伴发生

      • 问题诊断&故障定位

    • 多时序间的关联

  2. 关联可视化

    通过关联变动,帮助运维人员分析重点数据的变动情况。

    • 事件&事件关联
    • 事件&时序关联
  3. 服务透视定位问题

    运维事件多是与时间持续紧密关联,我们可以把运维事件按照时间轴演进顺序进行展示。同时,运维工程师常常接触的服务拓扑,本身也是一种运维模块的关联关系。把这些离散的运维数据通过模块关联、时间关联、数据流关联等紧密地联系起来,构成一个完整的服务透视图,如果异常发生在关系透视图中的某个部分,就可以按照周边关系的通路来快速定位问题。

    • 模块调用关系
    • 事件和模块关联

分析问题篇:故障定位

仅仅找到关联还不够,真正分析业务问题解决问题才是关键。这里介绍两个常用的辅助定位问题策略。

  1. 多维数据分析

    监控系统采集到的很多指标具备包含关系,很多情况下,一个总体指标是由许多子指标加和构成的,或者也可以说成是总体维度是由许多子维度组成的。监控系统可以计算出每个子指标或子维度占总指标总维度的百分比,并按照影响权重去进行分析,当某个子指标的变化幅度对总体指标影响权重,我们就倾向于认为这个指标可能是问题的原因。

    举个例子,百度的总体流量指标对应每个地域的流量之和,总体流量有问题有可能是某个地域流量出现问题,找到目前对总体流量变化影响的地域进行问题处理就可以解决问题。同样的道理也可以推广到其它情况。

  2. 故障诊断树

    运维人员可以通过数据可视化(热力图、多维报表)的形式,结合以前发现问题的经验沉淀模式,发现指标间的强相关,做出问题诊断。那我们是不是可以将运维人员的经验固化到监控系统中,通过不同指标的分析方向和下探方法可以形成树状结构,通过树上的某个节点进行逐级探查。最终形成故障诊断树,通过推导路径不仅可以帮助运维人员快速完成问题出现时的排查过程,节省这部分的定位时间,也很有可能达到直接定位问题或加速解决故障的目的。

    故障检测:

    • 领域专家知识
    • 逻辑推导引擎
    • 迅速找到问题根因

解决问题篇

  1. 单边故障自动止损

    单边故障指单个IDC故障、单个链路故障等。比如一个IDC或者某些IDC出现问题,解决办法是切走这部分流量,利用监控系统来做动态的部署调度。通过某个数据中心或链路的部署调整,帮助系统快速恢复,进而实现自动化决策和执行来实现单边故障止损。

    具体策略有:

    1. 实现自动冗余与调度
    2. 智能监控系统负责动态决策
    3. 部署调度系统负责调度执行
  2. 灰度发布自动止损

    研发工程师做灰度发布时,可以先做小流量的发布,部署系统可以跟监控系统配合,如果出现问题,直接进行状态终止或回滚,把问题控制在灰度发布范围内。

智能运维监控总结

通过上述说明,百度的智能运维监控系统最终形成了一个监控闭环,包含问题发现、分析决策和问题的解决。具体的组成包括异常检测、报警收敛、关联分析、故障定位和自动处理五部分内容。

未来运维变被动为主动

  1. 全方位覆盖

    在用户端(APP、浏览器等)、云端(机房、服务器、自身服务、第三方服务等)、管道(链路、运营商)等任何维度进行数据采集并进行异常自动检测。

  2. 让监控更聪明

    • 分析运用已有数据,并把服务状态、问题影响分析等可视化

    • 自动学习并理解故障的趋势和模式

    • 自动发现服务或依赖环境的变更

当然,更进一步地,监控系统是不是可以先于故障发生而预测到故障,在故障发生之前就可以处理并解决故障,从而达成产品的超高可用性目标。未来的智能监控应该是这样的,运维工程师经过完善的监控部署,实现全方位的异常自动检测覆盖,同时,在系统刚出现故障征兆,有损之前就进行处理并解决,实现完整的智能化监控系统解决方案。

微众银行:浅析基于知识图谱的根因分析系统

作为中国首家开业的民营银行和互联网银行,微众银行近年来业务发展非常迅速,海量客户和交易使 IT 系统的轻微抖动就可能影响众多用户金融交易体验。为了保证业务正常运转,全面提升 MTBF(平均故障间隔)和 MTTR(平均故障修复时间)这两个数字化运维的关键指标,除了需要迅速检测出异常,还需要快速、准确、有效地分析出异常的根因,迅速恢复。为了实现这一目标,微众银行运维团队在智能根因分析方面付诸了长期的努力,研发出了智能根因分析系统。目前基于该系统的根因分析准确率稳定维持在 80%左右。下文将具体阐述该系统的设计理念。

数据基础

“不积跬步,无以至千里;不积小流,无以成江海”。不论是人类专家或者是计算机,在进行分析、推理、决策时都需要数据的支撑。因此数据的准确性、及时性和完整性在根因分析中非常重要。在实现智能根因分析的道路上没有捷径,基于配置管理系统的 IT 运维系统群为其提供了坚实的数据基础。长期投入 IT 基础工程的研发,构建了较为完整的运维体系,在此基础上开始了智能化运维实践,接下来简单介绍根因分析主要应用到的数据。

配置数据

配置数据主要从 CMDB(配置管理)系统获取。CMDB 系统是众多运维工程师较为熟悉的系统,它包含了配置项全生命周期的信息以及配置项之间的关系(包括物理关系、逻辑关系和依赖关系)。从图 1 可以看出,从业务层到基础架构层,配置项与配置项间的关联关系都完整保存在配置管理系统内。智能根因分析可以从中获取到关联配置数据进行相关性分析。

图1 配置项分层

日志

日志主要包括 WEMQ 日志、业务流水日志和应用日志。WEMQ 日志是微众银行研发的消息总线系统所产生的日志,微众银行的系统间调用基本都要通过 WEMQ 系统来完成。业务流水日志是业务模块输出的日志(格式化的业务交易日志),它的内容跟产品和场景息息相关,记录了业务相关的信息。应用日志是应用程序输出的日志,包括一些异常堆栈信息。通过 WEMQ 消息的日志,我们可以分析出每一笔交易所经过的子系统及其调用情况,如下图所示:

图2 交易调用树

告警

监控系统可以说是 IT 运维的生命线,它集中采集了业务和基础架构相关的指标数据,并支持指标的实时计算,通过监控策略可以从这些指标或用户上报的数据中发现异常并生成告警,为 IT 运维的故障诊断提供了完整的数据支持。

监控系统提供了两部分的数据用于智能根因分析:一部分是实时采集的时间序列数据,即指标数据;另一部分是基于指标计算或者其他第三方系统上报的告警信息。

变更

变更系统提供了数据库、系统版本发布、主机、网络等一系列的变更操作和记录,所有的运维操作都要求必须在该系统上完成,因此该系统记录了内部全量的变更数据。基于这些变更数据,智能根因分析系统能够获取到跟异常相关的运维操作数据,并结合其他数据来进行根因定位。

图3 变更视图

技术选择

在根因分析技术的选择上,我们初期进行了探讨和调研。在异常检测方面,我们采用了深度学习、机器学习等技术,取得了不错的效果。但在根因分析方面,我们决定先采用专家系统的技术来实现,主要有以下原因:

  • 首先,“业务异常”的数据是“小数据”。正常的公司运营过程中,真正影响业务的异常事件数据本身就会很少,数据累积的速度会很慢。在“小数据”的基础上,机器学习在根因分析方面的应用相对有限。

  • 其次,“根因分析”是需要有较强的解释性的,每次业务异常后,运维工程师都会有完整的异常事件分析报告,机器学习在可解释性上相对较弱,而专家系统能更好的解释根因是如何分析出来的,更符合人类的思考逻辑。

  • 最后,利用人类专家“举一反三”的能力,可以短期内构建出根因分析系统。

因此我们先选择了专家系统的解决方案,将 IT 专家的经验总结起来形成推导规则。

专家系统和知识图谱

早期我们采用 Drools 规则引擎实现了基于规则的根因分析系统,通过不断丰富和完善推导规则,很快就使其具备了根因分析的能力。但在应用一段时间后,发现这个方案还存在不足的地方。主要有两个方面:

  • 首先是数据不透明。每一次异常发生过后,我们都需要检视根因分析是否正确。如果根因正确,那么就需要向团队内同步是基于什么样的数据和推理逻辑推导出根因的;如果根因错误,则需要检视是否存在数据缺失、推导规则错误等问题。团队把这一类工作叫做案例复盘。复盘就需要依赖当时获取到的异常数据来开展,原先我们把数据都放在 TDSQL 内,彼此之间相互不关联,所以复盘时这些数据都是碎片化的,数据透明程度差,复盘也相对困难。后来引入了图数据库,将异常数据以知识图谱的方式来存储,即方便查询,也方便展示。

  • 最后是规则维护困难。在根因分析系统早期版本的时候,推理模块是采用了 Drools 来实现的规则引擎,虽然它解决了知识和代码的耦合问题,但规则越来越多以后,从单个规则来看也很难看出整体的推导逻辑,维护起来相对困难。经过调整,我们在图数据库的基础上,按照不同的异常类型编写了推导模型,通过模型就可以在图数据库中找到根因。这样只需要维护好模型即可,降低了规则的维护难度。

根因分析设计

根因分析的总体思路是在异常事件发生时,系统收集信息并生成该异常事件的知识图谱,在图的基础上运用演绎推理和归纳推理等方法来对事件根因进行分析。简单理解就是图 + 统计 + 规则。根因分析将针对四种指标类型的异常:时延、交易量、业务成功率、系统成功率,再经过三个步骤的处理和分析:信息收集、根因定位、根因补充,最终分析出根因。从这个思路来看,异常事件的知识图谱如何设计,是我们根因分析设计的关键。接下来将详细介绍该设计,进而阐述根因分析设计的细节。

异常事件的知识图谱设计

异常事件的知识图谱是结合“动”态和“静”态数据来设计,“动”态数据包括业务流水相关的日志、证据数据,“静”态数据则来自于 CMDB 等配置系统。两类数据共同构建起一个完整的异常事件图谱。如下图所示,从图上可以看出,图谱是有方向的,从左到右进行根因的分析和推导,最终分析出根因。

图5 异常事件的知识图谱设计

一般来说,知识图谱设计及根因分析一般包括信息收集、根因定位、根因补充三个阶段。

首先是信息收集阶段,该阶段将收集用于构建知识图谱的完整信息,主要收集以下几个维度的信息:

  1. 事件:异常事件的起点,包含了异常事件的相关信息,例如事件的开始时间等。

  2. 指标:产品的关键指标,我们选择了四种类型的指标作为黄金指标,用于检测产品业务是否异常,每个场景都有其对应的黄金指标,其中包括:

    • 交易量:单位时间内的交易笔数。
    • 业务成功率:单位时间内的业务成功率,业务失败时该指标会下降。业务失败是指符合业务逻辑的失败,例如验证码未通过。
    • 系统成功率:单位时间内的系统成功率,系统失败时该指标会下降。系统失败时指系统内部的失败,例如连接数据库异常。
    • 时延:单位时间内完成交易的总耗时时间。
  3. 业务流水:用户在产品上操作所产生的编号,每一次操作都会产生一个唯一的编号,也称为一笔交易。这个编号可以关联出业务日志和实时树日志(WEMQ 日志)。

  4. 业务流水日志:每个系统按照规范打印的业务相关日志,可以从中查到具体的业务参数和相关调用信息。除了业务相关的信息外,日志中还有交易发生的子系统、主机、DCN 等信息。

  5. 实时树日志:之前提到的 WEMQ 日志,可以将交易的完整调用路径分析出来,其中还有经过的主机、耗时等明细数据。

其次是根因定位阶段,该阶段根据收集到的日志数据,对交易进行统计分析,并定位到哪个子系统、主机才是本次事件的根因。以系统成功率为例,在异常发生时,有多笔交易产生了错误日志,这时对异常时间点的交易信息进行提取,找到当时存在 n 笔交易是异常交易。对这 n 笔交易进行统计分析后,发现这些交易都在某个相同的子系统报错了,说明该子系统就是根因子系统。

最后是根因补充阶段。这个阶段会采用告警、变更等数据来进行分析,并对根因进行补充。如果定位到一个子系统存在异常,该子系统如果还存在告警、变更等数据的话,就会进一步的补充到根因内,使得根因更加具体、明确。

实际案例

整个系统的根因分析工作分三个阶段。接下来将以实际案例来简单介绍智能根因分析系统是如何工作的。

阶段一:信息收集

信息收集阶段以事件中心,关联查询异常相关的日志、告警、变更、配置等信息,用以构建该异常事件的完整知识图谱。

  1. 以事件为起点,关联查询本次异常事件相关的指标信息。
  2. 通过获取到异常时间点的业务流水信息,连带查询出对应业务流水号可以关联出来的业务流水日志和实时树日志。
  3. 获取当前存在的证据。
  4. 将所有数据写入到图数据库,生成知识图谱。

图6 异常事件的知识图谱

阶段二:根因定位

根因定位阶段是在异常事件知识图谱的基础上,应用推导模型,对存在异常的子系统,及其相关的、IP、DCN、服务信息进行提取,起到定位的作用,也对异常事件的知识图谱进行了裁剪。

如图 7 所示,应用图分析的推导模型后,异常的子系统及其相关 IP、DCN 及其证据从知识图谱中提取出来。

图7 应用了推导模型后的知识图谱

阶段三:根因补充

根因补充是为异常事件进行最终根因定性的阶段,在阶段二的数据基础上,应用规则引擎最终推导出根因结论。

从阶段二中已经可以清晰发现该事件的根因。所有高耗时实时树日志都指向的 APS 子系统,而此时高耗时实时树日志经过的主机和 APS 子系统都能关联到应用版本发布信息。通过该图获取到的信息,经过话术的加工,最终智能根因分析系统给的异常事件根因是:[应用版本发布]子系统 6009 AOMP 应用发布。影响:上游 DSFS 接口 激活,返回信息:激活成功(交易耗时异常升高)。

上述是时延异常的一个案例,通过三个阶段的分析,最终定位到是应用版本正在发布,导致服务的耗时异常升高。整体思路是通过收集系统异常时的相关信息,构建异常事件的知识图谱,再应用推导模型对图谱进行信息提取,最后应用规则引擎对根因进行推导。

结语

回顾这一年多的系统建设历程,我们最初梳理了根因分析的数据基础,在这些数据基础上确定了根因分析的方法,即以业务流水日志为抓手,将各纬度数据进行整合和分析;选择专家系统的方案来快速构建根因分析系统;还应用了图数据库和知识图谱的技术来解决数据透明和根因推导的问题。根因分析系统后继还会持续优化,历史上异常事件的知识图谱对我们也是宝贵的财富,记录了所有异常当时的全貌,为我们挖掘更多知识和优化推导逻辑提供了数据支持。

苏宁:基于 NebulaGraph 构建知识图谱的大规模告警收敛和根因定位实践

概述

知识图谱有较强的知识表达能力、直观的信息呈现能力和较好的推理可解释性,因此知识图谱在推荐系统、问答系统、搜索引擎、医疗健康、生物制药等领域有着广泛的应用。运维知识图谱构建相对于其他领域的知识图谱构建而言,具有天然的优势,网络设备固有的拓扑结构、系统应用的调用关系可以快速的构成软硬件知识图谱中的实体和关系。历史的告警数据蕴含着大量的相关、因果关系,使用因果发现算法,也可以有效的构建告警知识图谱。基于知识图谱上的权重进行路径搜索,可以给出根因的传播路径,便于运维人员快速的做出干预决策。

苏宁通过 CMDB、调用链等数据构建软硬件知识图谱,在此基础上通过历史告警数据构建告警知识图谱,并最终应用知识图谱进行告警收敛和根因定位。本文主要包括运维知识图谱构建、知识图谱存储、告警收敛及根因定位等内容。

痛点及产品对策演进

痛点:

  1. 苏宁内部系统和服务的复杂性:

    • 6000+ 系统,数量还在增加

    • 系统间调用方式复杂:大部分使用 RSF,也有 HTTP、HESSIAN 等

    • 苏宁业务的复杂:既有线上新业务又有线下老业务,这些业务系统之间会有大量的关联
  2. 基础环境的复杂性:

    • 多数据中心,每个数据中心会划分多个逻辑机房和部署环境
    • 服务器规模 30w+,例如,缓存服务器就有可能有上千台服务器
    • 设备复杂性:多品牌的交换机,路由器,负载均衡,OpenStack,KVM,k8s 下 docker,swarm 下的 docker等

基础设施的复杂性导致每天平均产生 10w+ 的告警事件,峰值可达到 20w+ / 天。面对海量的运维监控数据,系统和指标间关联关系越来越复杂,一个节点出现故障,极易引发告警风暴,波及更广的范围,导致定位问题费时费力。此时,单纯依靠人肉和经验分析,越来越难以为继。迫切需要一个工具,可以辅助我们分析系统和指标间关联关系,可视化展示告警的传播路径和影响范围等。

产品对策演进

针对上述痛点,我们采用领域知识结合 AI 的方法对告警进行收敛,以缓解告 警风暴。此外,为便于一线运维人员快速的作出干预决策,我们同时对告警的传播路径和影响范围进行分析。

  1. 基于交叉熵的告警聚类(1.0 版本)

    按照告警的场景和规则,利用交叉熵对告警信息进行聚类,实现告警的收敛。 借鉴 moogsoft 的思想,将告警聚类结果生成 situation,同一个 situation 中包含同场景、有关联的告警。

    缺点:

    • 收敛效果有限,该方法只能减少 30% 左右的告警,无法有效解决告警风暴问题;

    • 无法提供根告警以及根因链路

    • 弱解释性

    • 无法解决告警的根因问题。

  2. 基于 GRANO 算法的根因定位(2.0 版本)

    根因定位是在告警收敛的基础上进行的,采用 GRANO[2] 算法,基于告警收敛结果生成 situation,计算 situation 中每个告警节点的得分,然后排序来确定根因。

    缺点:

    • 这种方法的缺点是不会给出一条完整的根因链路,因此根因的可解释性不强。
  3. 基于运维知识图谱的告警收敛和根因定位(3.0 版本)

    包括全局视角下的软硬件知识图谱和告警知识图谱,利用 NLP 技术对告警文 本信息进行分类,然后将告警收敛到软硬件知识图谱的相关节点上,再结合具 有因果关系的告警知识图谱,得出一条 “A –> B –> C –> D”的根因链路。

    优点:

    • 由于结合了领域相关知识,该方法收敛效果更好,而且提供了一条完整的根因链路,所以解释性更强,可以更好的为 SRE / 运维人员提供指引。

思路与架构

分层建设思路:

流程架构:

运维知识图谱构建

软硬件知识图谱构建

软硬件知识图谱是以全局的视角展示系统内各应用、软件、虚拟机、物理机间 的内在逻辑,系统间的调用关系,网络设备的物理连接关系。图谱中的节点包 括系统、DU(部署单元)、group(主机实例组)、软件、虚拟机、物理机、接入交 换机、核心交换机、汇聚交换机、路由器等。关系包括 constitute(构成)、call (调用)、logical(逻辑连接)、cluster(汇聚)、ship(承载)、host(宿主)、connect(物 理连接)等。软硬件知识图谱的原型如下:

软硬件知识图谱构建的数据源主要有 CMDB 数据、调用链数据和物理设备网络连接数据。实践中首先基于离线数据初始化软硬件知识图谱,随着业务的变化和拓展会出现旧系统的下线和新系统的上线,然后根据变化定时或定期更新软硬件知识图谱。

CMDB 数据构建流程

通过 CMDB 数据可以构建 HOST->VM->SOFTWARE->GROUP 及 GROUP (WildFly) → GROUP(Nginx)的关系图谱。

调用链 / 物理设备网络连接数据

调用链数据主要用于获取 DU 间调用关系、系统间调用关系、DU / IP 映射关系、中间件间的逻辑连接关系等,数据主要通过内部的一些 API 接口获取。

物理设备主要包括物理机、交换机、路由器等,数据主要通过运维平台获取。

合并图谱

将前面得到的 CMDB、调用链和物理设备图谱通过 networkx 合并,然后存入图数据库 NebulaGraph 中,最终得到的单系统和系统间图谱分别如下(NebulaGraph Studio 可视化呈现):

其中蓝色节点为系统,浅蓝色节点为 DU,绿色节点为 group,红色节点为软件,橙色节点为虚拟机,深蓝色节点为物理机,黄色节点为接入交换机,淡黄色节点为汇聚交换机。

NebulaGraph Studio: https://github.com/vesoft-inc/nebula-web-docker

告警知识图谱构建

告警数据分类

原来的告警分类采用是交叉熵方法:告警信息、分词、统计词频、计算与各类别的相似度(交叉熵),若相似度大于阈值,选择相似度最高的那一类归到该类,若相似度均小于阈值,则新增一个类别。

缺点:

  1. 无法控制分类的数量,比如如果阈值设的较大,就会出现好多类别;如果设置的较小,很多告警又会归到一类。
  2. 无法控制类别的具体含义,分类依赖于交叉熵的计算结果以及阈值的设置,无法确切知道每个类别的真正含义。

上述这种方法无法满足我们构建因果图的需要。

为了让构建的因果图有更好的说服力和可解释性,我们需要对各种告警信息进行人工分类,比如有的告警是对应于基础设施,比如网卡流量,cpu 利用率,有的告警对应于具体软件,比如 mysql 延迟,wildfly 无法获取连接。这样,每个告警类别都有自己明确的含义。在此基础上构建的因果图才是有意义的。我们首先对 zabbix 六个月全量告警信息进行了整理,将所有告警分为了 183 类,然后使用有监督的方法,训练分类模型。这样新来的告警信息也可以按照 我们预先设定的类别进行分类。分类模型我们使用的是自然语言处理方法,先对告警信息进行分词,然后计算词向量,然后将词向量作为输入训练模型。我们分别训练的 cnn 和 bow(ngr ams)分类模型,整体而言,分类准确率都很高,能满足我们的要求。其中 cnn 效果好一点,但是预测时间也会比 bow 耗时长一点。

  • cnn 模型(modelcnn20e__0813):

    • train_list:predict total time= 12.386132

      总告警数量: 20620 错误个数: 0 准确率= 1.0

    • test_list:predict total time= 1.452978

      总告警数量: 3620 错误个数: 0 准确率= 1.0

    • 全部六个月告警信息

      总告警数量: 733637 预测错误数量: 9 准确率: 0.99998

  • n bow 模型(model__bow__20e__0813)

    • train_list:predict total time= 1.687823

      总告警数量: 20620 错误个数: 1 准确率= 0.999952

    • test_list:predict total time= 0.272725

      总告警数量: 3620 错误个数: 1 准确率= 0.999724

    • 全部六个月告警信息

      总告警数量: 733637 预测错误数量: 12 准确率: 0.99998

因果节点选取

因果节点不具体指一个物理机或虚拟机 IP 上的告警,而是对所有告警类型的一个抽象总结,目前包含三层(结构如下):物理机层面的告警、虚拟机层面的告警、软件层面的告警。比如任何一台物理机上的宕机告警都归类于因果图上【物理机-宕机】节点。

经过告警数据分类,我们初步将所有的告警分类都作为因果节点,在经过因果算法输出因果边并人工筛查确认之后,选取最终的因果节点。

构建因果发现样本


基于 6 个月的 zabbix 告警数据(如上图,共 781288 条告警)构建样本。

构建目标:

根据告警分类,已将每一条告警记录归类为一种告警类型(告警类型:物理机- xx 告警、虚拟机-xx 告警、软件-xx 告警)。以每条虚拟机告警记录为中心,给定一个告警时间切片(1min、2min 等),寻找每条虚拟机告警时间切片内的相关告警记录(相关告警包括:该虚拟机隶属的物理机上的告警,同隶属该台物理机上的其他虚拟机上的告警)集合作为一个因果发现样本。

举例说明:

下面是一台虚拟机在某一个时间点的告警,以该告警构建样本。

告警构建样本

给定时间切片为 1 分钟,以上面一条虚拟机上的告警为例,寻找 1 分钟内与该虚拟机相关的物理机和虚拟机上的告警,所有告警如下图所示为一个因果样本。

因果样本

最终转置每一个样本,将告警类型作为列名,集合所有的样本,若发生告警记为 1,不发生记为 0,生成最终的因果发现样本(因果算法的输入),如下所示:
因果算法样本

因果算法

采用已有的因果发现算法工具包:CausalDiscoveryToolbox,其中包含的算法有:PC、GES、CCDr、LiNGAM 等。

  • PC:是因果发现中最著名的基于分数的方法,该算法对变量和变量集的进行 条件测试,以获得可能的因果边。
  • GES:Greedy Equivalence Search algorithm(贪婪干涉等价搜索算法),是一种 基于分数的贝叶斯算法,通过在数据上计算似然分数最小化来启发式地搜索 图,以获得因果边。
  • CCDr:Concave penalized Coordinate Descent with reparametrization(参数化的凹点惩罚坐标下降法), 这是一种基于分数的用来学习贝叶斯网络的快速结构学习算法,该方法使用稀疏正则化和块循环坐标下降。

目标:

采用多种因果发现算法训练告警数据,基于各个算法输出的因果边再结合人工审查筛选确定最终的因果边(包含因果节点),边确定了,相应的因果节点也确定了。

举例说明,以 PC 和 GES 两个算法为例:

  • PC 算法输出的可能因果节点和边

    因果节点和边

  • GES 算法输出的可能因果节点和边

    因果节点和边

两个算法都发现了【host-服务器宕机】导致【vm-服务器宕机】和【host-服务 器宕机】导致【software-网页访问失败】等相同的因果边,经人工确认物理机宕机确实会导致其对应的虚拟机宕机和服务器上的软件访问失败,所以确定这两条边为因果边。

因果边的权重计算

因果边的权重采用条件概率计算,即:基于因果发现样本数据和因果发现算法给出的因果边(包括两个因果节点),【因节点发生告警的条件下果节点发生告警的次数】与【因节点总共发生的告警次数】的比值作为该因果边的权重。

举例:

截取部分的因果边及其权重:【host-服务器宕机】导致【vm-服务器宕机】的因果边权重为 0.99。

构建告警知识图谱

经过【告警的分类】–>【构建因果发现样本】–>【因果算法发现因果边】–> 【因果边权重计算】,最终生成所有的因果边及其权重。

基于 zabbix 的 781288 条告警数据,最终确定了 213 条因果边(如上图所 示),根据 213 条因果边的指向和权重,构建告警知识图谱(部分结构如下图所示),并将告警知识图谱写入图数据库以便持久化读取,后续的根因定位需从图数据库读取所构建的告警知识图谱进行分析。

知识图谱存储

图数据库引入

图数据库是以图数据结构存储和查询数据,图包含节点和边。构建运维知识图谱做根因告警分析等场景时,为了实时查询知识图谱,我们引入了图数据库,并将知识图谱持久化存储到图数据库中。另外,引入图数据库还有以下优势

  1. 图数据库在处理关联数据时的速度快,而关系型数据库在处理反向查询以及多层次关系查询的时候通常开销较大,无法满足我们的要求。
  2. 图数据库可解释性好。图数据库基于节点和边,以一种直观的方式表示这些关系,具有天然可解释性。
  3. 图数据库查询语句表达性好,比如查询一跳,两跳数据,不需要像关系型数据库那样做复杂的表关联。
  4. 图数据库更灵活。图这种通用结构可以对各种场景进行建模,如社交网络、道路系统等。不管有什么新的数据需要存储,都只需要考虑节点属性和边属性。不像关系型数据库中,需要更新表结构,还要考虑和其他表的关联关系 等。

图数据库选型

图数据库选型

  • Neo4j 开源版本不支持分布式,无法满足我们对多副本的需求
  • ArangoDB 是 多模态数据库,支持 graph, document, key/value 和 search,支持分布式部署,查询速度快
  • NebulaGraph 一款是国产的开源图数据库,支持分布式部署且部署方式比 ArangoDB 更轻便,查询速度快,腾讯、京东等公司内部也在使用。

在充分比较了以上图数据库的性能,以及社区的活跃性以及开放性后,我们最终选择 NebulaGraph。针对上述的三个图数据库,我们做了一个详细的性能 Benchmark 对比:https://discuss.nebula-graph.com.cn/t/topic/1466

告警收敛及根因定位

流程

针对告警数据的收敛和根因定位,可以分为以下主要几个步骤。

  1. 设置时间切片粒度:实时获取时间切片内(1min、5min 等)的告警数据

  2. 告警分类:针对原始的告警数据,结合具体的告警信息和监控项等信息,根据训练好的分类模型对原始的告警数据从 HOST、VM、SOFTW ARE 三个方面进行分类,例如: vm_网卡流量大、host_磁盘使用率过高、software_网页访问失败等

  3. 告警收敛:查询软硬件知识图谱将告警以系统为单位进行收敛,收敛格式如下,格式如下:

    系统 1: {软硬件知识图谱节点 1:[告警类型 1,告警类型 2…], 软硬件知识图谱节点 2:[告警类型 1,告警类型 2…]

  4. 告警因果图构建:基于告警收敛结果,在图数据库中按照系统级别查询每个系统下的所有节点之间的连接子图,并将得到的结果输入到 networkx 中,得到某个系统下的各节点之间的最终连接关系,即告警因果图

  5. 根因路径:基于上述生成的告警因果图,以及权重来计算疑似路径,排序给出根因路径

告警收敛

基于上述的主要流程,我们现以时间粒度为前后 5min 内的告警数据创建时间切片样本,并取告警数量最多的前 100 个时间片的样本作为主要分析的内容,其中第一个时间切片中的各个系统下各节点的告警收敛结果如下:

告警收敛

根因定位

对于上述第一个时间切片中的某个系统,在图数据库中查询该系统下的所有节点构成的子图,以 “苏宁 XXX 系统”这个系统为例,查询得到在“一跳”范围内与该系统下的所有节点之间有关联的节点的关系大致如下(红色表示物理机节点,棕色表示虚拟机节点,绿色表示软件节点):

子图

上图中出现的所有节点中,既包括有告警信息的,也包括没有告警消息的,因此将上述因果图输入到 netwokx 后,可以得到最终经过精简后的有告警消息发出的各节点的因果图,其中一部分的因果图展示如下:

因果图

可以解释为:“192.168.xxx.xxx-host-服务器宕机”导致 “10.104.xxx.xxx-vm-服 务器宕机”,进而导致“software-网页访问失败”。

进一步的,根据上述生成的因果图,再结合因果图中每条边的权重,就可以计算出该时间切片下的单个系统层面上的所有疑似根因路径,经过排序后即可得到最终的根因路径。本例中最终得到的几条根因路径如下:

根因路径

从上图可以看出,程序最终给出了几条疑似的根因路径,其中包括最长的一 条,可以解释为:ip 为 192.168.xxx.xxx 这台物理机由于网卡 overruns 的原因,导致了这台物理机的宕机,从而使得这台物理机上的 ip 为 10.104.xx x.xxx 的虚拟机宕机,最终导致这台虚拟机上的相关的网页访问失败。

效果及优化方向

  • 在告警收敛方面,经过验证,基于运维知识图谱可缩减至少 50% 的告警量,最高可达到 60% 以上,有效率的缓解了告警风暴的压力; 另外,在时效性方面,基于 1、2、5min 不同长度的时间切片进行告警收敛,耗时可以控制在 6 s 以内,满足告警通知的时效性要求。

  • 在根因定位方面,经一线运维人员验证,每个告警时间段提供的可能根因传播路径集合基本包含了真实的根因,有效缩短了运维人员的干预时间;另外在耗时上,根因定位可以控制在 3s 以内,速度较快,满足时效性要求。

  • 但目前通过因果发现算法自动构建的告警知识图谱准确率有待进一步提升,继续调研评估其他告警知识图谱构建方式。继续完善软硬件和调用链告警知识图谱,当前仅是基于 CMDB 和 Zabbix 告警数据构建运维知识图谱进行告警收 敛和根因定位,基础设施层面的告警数据更简单、规范,后续还要扩展到更复杂的非基础设施层面的告警数据中。当前还没有利用知识图谱对异常检测(时间序列数据)结果做根因定位的应用实践,这需要对时间序列做因果关系的发现,构建时间序列之间的因果图,从而打通知识图谱与异常检测的壁垒,这也是知识图谱后续使用的扩展方向之一。

总结

简单总结一下:

  • 百度和微众银行将专家规则做成知识图谱来完成推理定位
  • 苏宁将历史数据提炼成因果图来完成定位并给出故障传播链路
一分一毛,也是心意。