海量业务的挑战
互联网业务讲究“极致、口碑、快”,经历过长时间的演进,腾讯SNG社交平台产品用户访问量已经达到亿级、十亿级, 我们的业务监控、业务分析等数据也显示:业务前、后端成功率都已经达到99%, 99.9%以上。 但随之带来的挑战也是显而易见的,例如:
1. 长时间历史的发展,导致后端架构复杂,功能模块众多、监控系统多、告警量大,如何简化,让告警简单、有效?
2. 关键业务成功率, 0.01%的指标告警都可能引起成千、上万用户的体验问题,且有可能存在着业务隐患。如何及时发现并及时处理?
3. 业务模块众多,在全局监控数据中,体现的监控组合维度成千上万(如省份、运营商、客户端版本、命令字等)、不可能为每一种业务设定阈值,如何实现无阈值告警?并且能准确定位到相关故障的表现维度?
AI应对
面对以上的运维带来新的挑战,我们的运维团队也在积极应对,历史上尝试多种方式,取得了一些成果,最终,我们采用AI的方法来进行了实现 。
这篇文章是腾讯社交网络运营部社交平台运维组针对社交平台(QQ空间、微云、相册、天天P图等)运维场景做的一系列工作,在原有监控数据的基础上,设计了“智眼”系统,实现了对KPI曲线的异常检测、智能多维根因分析,以及告警关联分析,旨在提升开发、运维定位问题的效率。
这个系统基于部门已有平台,同时从用户体验角度出发,打通客户端、接入层、后台逻辑层(平台持续扩大建设中)数据。进行了一系列业务相关的分析和探索
织云监控体系
在介绍我们这个系统之前,先介绍一下织云监控体系:
织云监控系统按监控机制,可以分为主动监控、被动监控、旁路监控:
1. 主动监控–一般采用从组件框架埋点,或从业务代码埋点,上报业务数据到监控系统,监控系统对其进行集中监控。如主机状态监控、业务模块间调用等。代表性产品包括: 模块调用监控、哈勃多维分析、全链路监控、业务生成监控等;
2. 被动监控–无需埋点, 一般采用拨测系统模拟客户端从外网发起请求等形式对业务进行测试,测试数据集中上报表监控系统,对其进行集中监控。代表性产品包括:织云返回码监控、 H5测速监控等;
3. 旁路监控–无需埋点, 在不接触业务本身的情况下对业务进行监控,比较典型的是舆情监控,对外网的舆情进行搜集,进行统一监控。代表性产品包括:天王星舆情监控等。
我们暂时使用了织云监控系统的一小部分数据, 其实基于腾讯织云监控体系的数据,可以做的事情还有很多。
数据源获取
我们获取的数据源有:织云哈勃多维分析(简称:织云哈勃)、织云模块调用分析(简称织云模调)、织云业务生死指标监控(Dead Live Point, 简称织云DLP)。
多维分析
通过客户端逻辑埋点,将相关数据通过统一的上报接口,透转到监控系统,监控系统将数据汇聚为多维统计数据,一般包含以下维度信息:
-
省份、运营商、网络制式,平台类型(安卓/IOS), 客户端版本等基础维度;
-
业务特性相关维度(比如直播相关的主播端、观众端区分),命令字;
-
指标相关数据(返回码、耗时)。
模块调用链分析
由产品,区域,模块,主调,被调,接口组成的一个监控(如下图),指标是成功率(基于返回码计算)和耗时。针对成功率监控,主要使用阈值策略,每分钟一个粒度,连续5次达到告警阈值,则产生一条告警,并一小时同一告警收敛到一次。
业务生死指标监控
DLP: dead live point, 即业务生死线指标监控,顾名思义,它很关键,它的告警关系到重要业务逻辑,直接影响用户。 只有重要指标才会配置到 DLP 平台,一旦告警,必须及时解决。一个 DLP 指标可含多个模调,一个模调也可以配置到多个 DLP 指标中;DLP 指标不止包含模调,也可以包含其他监控数据(如 Monitor 等),这里先略去。
如下图为其中一个名称为“与我相关_上海”的 DLP,涉及4个模块,配置了4个模调:
DLP 对成功率的检测与模调不同,无阈值,而采用 3sigma 检测策略。简单来说就是一个正态分布数据,超出三(可调)个标准差以外的数据,标记为一个异常,再叠加去除毛刺逻辑。告警收敛策略为半小时收敛一次,若未恢复,最多连续告警三个小时。
技术实现
我们做了什么?如下图,异常检测模块依据哈勃监控曲线检测异常;根因分析模块利用决策树分析出异常汇聚维度,再利用关联规则分析定位到后台模调异常,以及多个模调告警之间的异常传播链路。
业务异常案例
接下来,借用其中一个业务异常案例贯穿本文始末,依次介绍几个模块的实现详情及相关思考:
异常检测
针对曲线波动检测的基础逻辑为 3sigma 变种,增加了滑动窗口策略。原始时序数据每分钟一个粒度,滑动窗口取5分钟,将时序数据转化为5分钟滑动窗口的均值。滑动窗口可弱化一部分毛刺的影响,并且在检测出异常点后再加收敛策略,连续3个点异常,产生一条告警,进一步过滤毛刺。
如上图案例,最终告警信息为:
wns_dispatch(**wns) 业务成功率下降 0.24%
检测到告警后,将中间统计数据传给根因分析模块,分析异常汇聚维度。
根因分析
下图为根因分析后,rtx群告警信息:
此告警反馈出如下信息:
-
两个维度上的异常,从节点异常率汇聚上看, **.disk_get.** 问题最严重,从异常量汇聚上看,**.disk_photo.**最严重。
-
针对接入层告警,如果最终根因汇聚到某命令字维度,则通过配置文件正则匹配以及 L5 路由配置,获取此命令字对应的后台模块及其负责人。
如何实现根因分析?答案:将数据特征工程处理后,利用决策树分析汇聚维度(决策树可解释性强)。
大家熟知的机器学习算法都要包括模型训练,模型预测过程,这里对决策树的应用并非利用它预测的功能,而使用它的实现原理:树分叉时总会选择使得子集 gini 不纯度下降最快的一个特征,而这个特征正好代表了异常汇聚所在。因此,这里将数据输入决策树后,获取树的划分结果,然后我们根据需要从这个树中解析到所需的信息。
在这之前, 有一个必不可少的过程,特征工程(数据预处理),这里简单列几条需要注意的,其他细节略去:
-
one-hot 编码做特征处理
wns 的数据在哈勃前台配置了如下几个维度:
维度中的文本信息需要转化为数值,那么应该如何将文本转化为数值?如果转化为连续的数值,对决策树来说,这些数值就有了大小关系,而一个维度下的不同值是相互独立的,离散的。用 one-hot 编码来解决。如命令字这个维度,one-hot 编码前后如下:
即将一维的数据转化为二值化0和1的多维数据,特征转化为 commandid==**.disk_get.** 这样的判断条件,条件为真,结果为1,否则为0.表格中 commandid 举例了3种取值,则转化为3维特征。
将所有维度做了 one-hot 编码后,将8个维度扩展为上千维度(特征)。我们要做的就是从这上千特征中找出汇聚点。
-
数据指标(标签)处理
输入决策树的数据需要区分正负样本,可根据业务实际情况调整。举个例子,成功率这种指标,如检测到从99%下降到98%,那么此时必然有高于98%的数据和低于98%的数据,才可能造成整体98%的指标。可将98%作为区分正负样本的阈值。
-
数据还原
我们依据成功率划分正负样本,成功率来自某些维度上的统计结果,需要将原始数据量还原。以城市为例,深圳100人,香港1人,它的影响程度不同,需将深圳的统计数据还原为100条。
-
数据抽样
正样本比负样本多,输入决策树时负样本全取,需将正样本抽样使得正负样本比例1:1.避免因量级差异大而弱化负样本的影响。
接下来是决策树的使用(树拆分的收敛条件,参数略,可根据实际情况调整)。来看这个例子:
这是将内置的树结构输出的图形(节点上负样本在前,正样本在后),我们需要提取出这些信息:
-
哪个维度(节点)上异常聚集率(图中 rate_unormal)最高,也即 gini 最小。
节点异常聚集率 rate_unormal=(节点负样本数量)/(节点正样本数量+节点负样本数量)
-
哪个维度(节点)上异常检出率(图中 rate_recall)最高,也即负样本最多的节点。
节点异常检出率 rate_recall=(节点负样本数量)/ (树负样本总量,即根节点负样本量)
-
前二者的加权平均,类似机器学习界指标 f1-score。
这三个指标会选中三个节点(可能有重复),然后沿着树图,向父节点回溯,即可将这个节点的路径打印出来,如本节开端的 rtx 告警信息所展示。
补充一点,到这里有同学可能会问,日常运维中,总有一些维度上的数据是持续异常的,决策树会不会找到这些点,进而忽视了真正问题点?这里做了两个研究:
1. 用测试数据验证持续异常数据的影响程度
以空间为例,正常情况下,成功率持续未达99%的维度下数据占比4.24%,在正常数据上制造异常,观察决策树分析效果。下图四个测试的异常数据占比不同,最低的只有0.53%,但三条路径中总能有一个命中真正的根因。对于异常数据很少的场景,根因中会有一些冗余维度的影响,比如‘中国移动-北京市’的仿真异常,最终输出的效果可能是:platform !=PC, isp='中国移动',city='北京市',这种影响基本可控。
2. 模型加入预测过程,来去掉冗余信息,可根据性价比考虑是否采用。
关联分析
关联分析有两块内容:
-
与 DLP 生死线告警的关联;
-
与普通模调告警的关联。
1. 前台页面展示同时段 DLP 告警:
2. 模调告警(结合 DLP 中模调合并去重)关联分析:
首先,关联规则怎么获取?取历史告警数据,分析A告警与B告警之间的关联。当A,B再同时告警时,直接展示关联关系,聚焦到根因模调,解决即可。因数据仅基于告警,历史上很少告警的模块关联关系是获取不到的,也是后续需要去考虑的问题。
提起关联规则,大家都会想到 Apriori 和 FP-Growth 算法。
-
Apriori 算法支持提取频繁项集和关联规则,FP-Growth 算法仅支持频繁项集。
-
Apriori 在提取频繁项集时需要频繁遍历原始数据,效率非常低,FP-Growth 算法仅遍历两次原始数据,但却不支持关联规则。
这两个算法目前还没有一个经过验证有效的公共库可以调用(网上很多算法实现是有问题的,需要注意),需要自行研究实现。
我们需要使用关联规则,但 Apriori 的效率用于工程实现是不现实的。这里仔细研究了 Apriori 和 FP-Growth,对 FP-Growth 做了适当改造,在提取频繁项集的同时获取其支持度,进而基于频繁项集,利用 Apriori 的思路,获取关联规则(算法详情目前输出在内部)。
告警关联规则获取策略
我们的告警关联规则如何获取?数据来源不同,策略不同:
1. 针对模调告警:
支持度:30
置信度:80%
取过去两个月告警数据,同时告警30次以上的模调构成频繁项集,A告警引起B告警的概率超过80%,则形成一条 A->B 的关联规则
2. 针对DLP告警:
支持度:3
置信度:80%
因 DLP 配置的模调都是业务核心模块的核心指标,基本很少告警,支持度设置的较小。并且事实上,从 DLP 中模调获取的有效关联规则,真实置信度基本都是1.即A告警,B一定会告警。
两种来源的关联规则合并去重后,就产生了我们的规则库,由{warn_from},{warn_to},probabiliy构成一条关联规则,意思为:warn_from 发生后,warn_to 会发生的概率为probability。 warn_from,warn_to 都是一个集合,可能存在多条。而 warn_to 我们只取一条的即可,因为若一个告警导致{A,B}同时发生,那么它导致A和B单独发生,也必然成立。
离线获取关联规则后,当实时告警发生时,利用关联规则去匹配,命中规则的告警,可画出告警链条。在这个案例上,检测到哈勃 KPI 曲线异常,分析了聚集维度,进一步获取后台模调告警,分析如下:
共5条模调告警(格式:产品标示#模调区域_模块名称_主调_被调_接口)
4条命中关联规则,收敛到 1 条根因,为网盘 2.0 拉取问题,架平 ckv 接入机故障。开发、运维定位问题时从如下视图中即可直观看到问题点。
接下来简单介绍下如何根据关联规则,分析根因模调:
抽象来说,A,B,C 同时告警,命中了两条规则
B是A的结果,又是C的起因,可画出一个告警链条:A->B->C ,即 A,B,C这三条告警根因是A。
针对这个案例,截图一部分告警链条如下:
请注意:告警链条并不一定是真实的调用链路,它的目的仅在于将告警串起来,而不是分析调用关系。
总结
最后,总结一下,异常检测模块监控KPI曲线,成功率下降0.24%,根因分析模块分析出异常汇聚在**.disk*相关模块上,进而关联分析模块从同时告警的5个模调中找出根源,为网盘2.0拉取问题,将异常定位流程从客户端、接入层到逻辑层打通,告警时直接展示根源,缩短了问题定位时间。
原文发布时间为:2018-04-5
本文作者:李春晓