本文根据徐新龙老师在〖2023 中国数据智能管理峰会-上海站〗现场演讲内容整理而成。(文末有PPT获取方式,不要错过)
讲师介绍
徐新龙,蚂蚁集团AIOps技术专家,在蚂蚁基础设施团队从事关于SLO的健康度体系建设,以及异常检测、故障定位、预案推荐等场景下的AIOps实践;曾就职于携程技术保障中心SRE专家岗,负责AIOps的实践探索和落地,以及多个AIOps产品的设计研发。
分享概要
一、SLO介绍——为什么需要SLO
二、SLO健康度——从0到1构建SLO
三、AIOps赋能——SLO和智能化结合
四、案例介绍——实践场景和运营探索
五、总结
精细化运维是运维演进的必由之路,是综合业务需求、研发效能、稳定性保障、成本优化、架构治理等多种因素驱动的必然结果。为了实现精细化运维,首先要完成运维的数字化转型,管理学大师[美] 彼得.德鲁克说过,If you can't measure it, you can't manage it。在实践中,我们存在大量的运维数据,如何让这些数据充分发挥价值、形成对企业有用的资产,是我们探索和实践的主要方向之一。
本文的分享主要围绕SLO体系建设展开,在相对标准、统一的框架下指导和推动服务质量的数字化建设,结合具体的运维场景和背景,沉淀对组织有价值的数据资产和流程规范。同时分享了一些SLO运维实践案例供大家参考,希望有所启发和收获。
一、SLO介绍——为什么需要SLO
在展开SLO(Service Level Objective)介绍之前,我们先从一个熟悉的运维场景出发,希望通过具体的案例可以让大家快速代入。
值班处理故障,是大多数SRE和运维工程师的日常。在蚂蚁,基础设施负责的K8S,提供面向集团所有二方系统的算力交付,SRE的职责之一就是保障交付质量和稳定性。好几年前的某天,我们在Pod交付的用户群接到报障,反馈的现象是二方系统无法创建Pod资源或是交付时好时坏,接收到用户侧报障之后,值班SRE就展开了一些列的问题排查,这是一个典型的故障驱动型的问题发现。
众所周知,K8S是一套非常复杂的系统,由众多的组件协同来异步完成资源交付。简单概述下排查的思路,因为用户报障现象是交付失败时有发生,并非完全不可用,所以最先怀疑的方向是请求容量是否有激增,导致调度任务积压,通过监控查看队列也确实如此,为了避免任务重试导致队列进一步积压,执行了一些列的降级操作,随着时间的推移,故障有所缓解,但并没有得到彻底修复。直到第二天,通过变更排查,定位到调度器的规格大小被做了limit限制,这意味着调度器组件将无法像之前一样“贪婪”地使用到宿主机的空闲资源,进而导致处理能力受限。
简单复盘这次故障的时间线,调度器在5天前被限制了规格大小,导致调度任务队列逐渐积压、耗时增加,之后的Pod交付成功率受到影响并产生告警,通过一些列降级手段进行干预,有所好转但实际并未根治。终于在调度器“带病”工作5天后,接收到了来自用户侧的报障。
针对上述提到的这个“不完美”案例,相信大家可以提出一些列的改进建议和措施。然而,我们重点想要讨论的并不是具体的方案,而是一种架构治理和运营的模式,如前文提到的,这是一个典型的故障驱动型的事件。日常中,变更往往是导致故障最根本、最直接的根因,在经典的故障驱动治理模式下,为了避免故障和错误,在实施变更前后,一般会包括事前的变更管控、风险左移,事中的应急流程,以及事后的监控覆盖等步骤。在面向过程的资源交付场景下,这个套机制没有任何问题。
但是,在以K8S为代表的云原生交付体系下,面向终态的声明式操作逐步替代了早期的面向过程式的运维模式,经典的故障驱动型治理模式,逐渐暴露出了一些问题,强调是否产生故障或事件大过服务质量本身。随着运维精细化的演进和架构治理需要,我们需要一种贴合云原生、更普适和体系化的模式来驱动日常运维。
同时,围绕云原生的应用生态已然成为了当下最主流的交付模式,企业上云也是快速开展业务和节约成本的最佳选择。企业上云之后可以不用关心底层的网络结构、计算资源、存储、中间件、负载均衡等技术细节和实现,只要专注于业务逻辑的研发即可。显然,上云提效的同时也失去了对于底层基础设施能力的掌控力。基础设施能力不透明、云厂商操作不可见,对于上层业务系统的稳定性都是巨大的风险隐患。因此,云服务质量的公开、透明化是企业选择上云与否以及选择哪家云厂商重要考量因素之一。
另外,组织协调也需要共同的目标。在应用生命周期的不同阶段,会存在不同的角色分工,比如研发负责应用的功能开发和性能优化、SRE保障应用运行的稳定性和安全等,跨团队协同需要有一致的共建目标来驱动应用架构的迭代和演进。因此,我们需要一种有效、可量化的机制对齐和牵引不同团队间的合作。特别的,SRE需要及时将软件缺陷和系统风险同步到研发侧,确保系统运行期间的高可用性。故障驱动型的运营模式下,通过故障复盘来组织协同是常见的形式,主要问题是存在滞后性。如何主动提前识别到服务异常、系统风险是稳定性建设的核心诉求之一。
通过前面的案例和背景介绍,相信大家已经很清楚我们接下来要介绍的内容了。在实践探索中,我们通过建设SLO体系有效地解决了上述提到的问题,为精细化运维提供了的有力数据支撑和数据资产建设规范。借助SLO数据,针对不同的运维场景抽象、建设和组合相关的能力,让SLO体系实践落地具备普适性和可借鉴意义。
接下来我们介绍下围绕SLO的几个关键概念:
系统具备可观测性是构建SLO的前提,系统需要具备一个或多个监控指标来反应某些维度上的服务能力,将服务水平跟观测指标绑定。SLI(Service Level Indicator)的选择和指定主要取决于服务哪些维度的能力需要被观测到,以及现有的监控指标和手段是能够否覆盖到,亦或是需要设计开发侵入性的代码逻辑来实现。简言之,SLI提供了服务水平的可观测性。
SLI提供了应用或系统服务能力和服务水平的可观测性,SLO是针对其量化结果设置的目标,用以承诺和管理用户对服务水平的预期。这种对预期的声明式公开透明的、确定的,对于服务的不同消费端是一致的、无差别的。同时,SLO的结果可以用来通晒,对齐多方对于服务水平和服务能力的认知和共识,以此改善用户间的沟通。此外,还可以利用SLO的结果平衡研发效率和系统稳定性,当SLO不达标时,反映出稳定性受到挑战,则需要放缓研发效率,投入更多的精力在稳定性建设上。
以系统可用性SLO为例,当服务端承诺月度SLO为99.9%时,说明系统在以月为统计窗口的时间片结算时,其不可用时长不能超过43分钟,超过则认为当月服务质量不达标。显然,可用性目标设置地越高,意味着可接受的宕机或不可用时长更短。为了达成更高的目标,往往需要付出更多的投入和努力。
SLA(Service Level Agreement)的制定,是为了约束和监督服务方对于SLO承诺的履行结果,包括针对SLO运行不达标的惩罚和补偿说明。比如,所有云服务厂商都会对其销售的服务出具SLA,主要包括服务介绍、度量服务质量使用的SLI、对客承诺的SLO、以及结算不达标时的补偿方案等内容。
以AWS(Amazon Web Service)上的云服务器ECS(Elastic Compute Service)为例,该服务的SLA协议中明确指出了一旦服务水平不达标之后,在费用上会给出何种优惠措施,优惠的粒度会依据SLO不达标的程度区分出不同的档位,并且当SLO破线到一定阈值后,将返还购买该服务的所有费用。
根据前面的介绍可以看出,SLO体系之所以可以运转的核心驱动力来自于SLA。但是针对内部的应用和服务,我们不能像云服务一样,通过成本价格约束SLO的执行情况,因此需要寻找一种等价约束力来驱动SLO运营成了关键问题。实践中,我们会将不达标的SLO结算成不同等级的技术风险事件,通过稳定性相关的例会透出通晒和治理。
域内公示SLA也是我们运营的重要环节,如下是一份SLA公示模版。通过SLA公示将服务等级公开透明地传递给消费端,以此对齐消费端预期。公示审批的过程中,促成上下游服务之间握手、达成共识,打造SLO驱动的技术氛围和文化。
实践SLO,概括下就是在相对标准、统一的框架下指导和推动服务质量的数字化建设,形成对组织有价值的数据资产和流程规范。借用在人工智能和机器学习领域的观点,算法的上限受限于数据质量的好坏,所以从源头上建设高质量的数据非常重要。
对比传统的基于Metric的明细监控,SLO健康度体系的构建更加聚焦服务核心的能力和质量。一般地,SLO的制定需要业务方、研发和SRE共同约定协商,然后由SRE主导产出度量指标。因为SLO设计之初只关注应用或系统向外输出的服务能力和服务水平,天然屏蔽掉了大量细粒度的告警干扰,值班人员只要关注各自运维系统的SLO告警即可。通过践行SLO健康度体系,应用或系统的服务能力和服务水平得到了更好的度量和数字化,避免了传统基于metric监控中的大多数问题。同时,在参与建设SLO过程中,SRE可以进一步了解和剖析系统,这样也提高了SRE对于系统的掌控力。
二、SLO健康度——从0到1构建SLO
和大多互联网企业一样,蚂蚁的基础设施侧存在众多的异构系统,被上层的业务应用和服务所依赖。考虑到不同系统的技术栈、架构、部署等因素,我们需要找到一种通用的、泛化性强的数字化方案指导和构建基础设施域内的健康度体系。基于这样的客观现状,我们开启了蚂蚁基础设施域内从0到1的SLO健康度体系建设和实践。
基于SLO的健康度体系具备很多优势,然而所有的提升都是需要代价的,在建设SLO过程当中也需要更多地投入,这也意味着我们迈进了精细化运维的阶段。从整体上看,我们把SLO的健康度体系分成了4层结构: 最下层是目标系统的运行层,是提供服务的对象实体,包括基础设施域内所有提供服务的应用和系统;其上是SLO的数据层,数据层包括SLI数据收集、SLO数据加工、数据展示、SLO元数据建模、数据清洗、以及常见分析的数据抽取等;再之上是基于SLO数据的场景分析处理能力层,包括基于场景的更高级的数据分析能力、异常检测、故障发现、故障定位、预案关联、以及相关产品建设等能力;最上层则是基于场景能力划分的应用层,用于数据通晒的SLO健康度大盘、健康度应急流水线、辅助计价和成本分摊等应用,赋能到质量、效率、稳定性、成本等具体场景中去。
实践之初,我们主要是基于GitOps和Prometheus来构建SLO健康度体系。通过Git管理SLO相关的定义和元数据,以Yaml的形式推送到部署在K8S集群的Prometheus上,Prometheus会按照Yaml中定义的规则抓取、计算和存储目标系统的SLO数据,结合Grafana实现SLO数据的透视和可视化。同时,基于Prometheus上配置的Recording rules可以实现基于SLO的告警能力,再结合电话、邮件、钉钉等渠道完成告警通知。另外,利用Prometheus的SLO告警和时序数据,我们实现了故障发生时的异常检测、定位和下钻能力,再加上故障管理过程中沉淀的历史专家经验数据,针对部分运维场景实现了基于故障定位结果的预案推荐,打造了基于SLO健康度数据的一站式应急解决方案。
具体地,利用Prometheus计算生成SLO数据,只需要简单掌握常用的PromQL(Prometheus Query Language)并编写相应的Recording rules,通过Git代码仓库维护管理SLO元数据的版本及分支,再通过ArgoCD将对应的Recording rules配置推送到Prometheus并重载即可生效。
为了更好的利用SLO数据,我们简单介绍下Prometheus中的数据模型。Prometheus属于单值数据模型的时间序列数据库,监控数控是由时间戳、监控数值及标签组构成。
同时,Prometheus还支持了非常丰富的OLAP操作以便于对时序数据进行钻取和透视。另外,Prometheus提供了UI Explore功能,对PromQL提取到的时间序列数据做简单可视化。从纯数据合成的视角,SLO序列是对空间维度和时间粒度更宏观的聚合:空间(数据横截面)上,聚合掉标签维度信息,只关注整体;时间尺度上,以天、周、月、季度等分辨率统计和计算,从而形成了无标签或低标签维度的时间序列数据。如之前所提到的,SLO关注的是统计窗口内应用或系统整体的服务能力和水平、是宏观健康度的反映和度量,比如政府报告中不会罗列出每个具体区域的GDP明细,而是汇总成宏观经济指标对外公布。
为了扩展SLO在具体的运维场景中的应用,使得依赖相关性定位变得更加通用(将在第三部分介绍),结合SLO元数据,我们定义了一些扩展概念。
Prometheus的数据模型,一条SLO数据是由时间戳、监控数值和众多的维度标签构成,每一组标签代表了该条数据的归属,即将该条SLO数据可被分解的方向,于是我们引入了服务水平影响因子(Service Level Factor,SLF)。在构建SLO数据的过程中,我们将可能会影响到服务水平的维度注入到SLO数据中,以便在SLO序列预警的时候,遵循相关的维度对异常进行下钻,从而定位出故障信息。
受限于单条SLO数据所能携带的维度信息量有限,以及维度信息过多会导致异常下钻时需要遍历地笛卡尔积空间过大,会导致大量的算力消耗,以至于影响定位效率。针对这些问题,在SLF基础上,我们又拓展了服务水平依赖(Service Level Dependencies, SLD),将相关的SLO数据集或监控集作为某一个SLO的依赖项,用来构建可能的故障传播路径。在依赖相关性定位时,不同的SLO或监控指标之间可以通过共同的维度传递下钻信息,以此挖掘出潜藏在上下游系统中更多的异常信息。
和传统的直接设置固定阈值预警不同,利用SLO序列发现异常时,我们引入了错误预算的概念(Error Budget)。客观地,应用或系统发生错误在所难免,因为上下游的依赖异常、网络异常、存储异常、运行时异常、以及配置变更导致的错误,都可能导致应用或系统不可用。SLO本质是对服务质量(成功率、可用时间等SLI)的预期管理,反过来对错误做预算管理,也可以起到等价的效果。例如某个应用成功率的月度SLO设置为99.9%,则这个月总的错误预算就可以表示为(1-0.999)*月度总请求量。为了SLO能够达标,必须合理地支配和消耗错误预算,一般地,我们把这个过程又称作错误燃烧。
尽管引入了SLO错误预算作为故障预警方案,实践中还是会支持像固定阈值这样的简单告警方法,针对不同应用场景灵活地选取适合的解决方案。接下来我们按照由易到难、由简到繁的次序介绍下SLO预警的常见方案。因为SLO序列大都由长时间窗口统计计算而来,在灵敏度上不容发现故障,故而可以采用较短的时间窗口计算错误占比,一旦错误率超过了固定阈值,则发出告警通知。实现容易、解释简单,不依赖历史数据。对于成功率类型SLO序列,月度目标设置为SLOm、短窗口错误率告警阈值设置为1-SLOm时,如果当月不发生告警,则SLO必然达标。
燃烧率(Burn Rate)是指将总的错误预算均匀地分配到告警窗口中的系数。比如月度SLO刚好达标时,将错误预算刚好消耗殆尽的燃烧系数定义为1,故当燃烧率为2时,错误预算会在月中被消耗完,然后SLO破线不达标。基于这些概念,我们就可以用公式简单推导出触发告警所需要的时间,即告警灵敏度。同时,我们也可以大致估计出,告警触发时消耗了总错误预算的比例。
利用错误预算和燃烧率,在告警发生时,我们可以大致推算出本次告警对SLO的威胁,因此设置不同的燃烧速率,可以有效预估告警的严重程度。
根据不同燃烧速率的SLO预警指定告警程度,再为不同级别的告警配置不同的通知渠道和接收人。同时可以结合精度不同的告警窗口,设置更加灵活的多消耗速率告警,既保证了告警发现的时间分辨率和敏感度,也能保持良好的召回和准确率。当然,该预警方案的缺点也非常明显,需要设置多个窗口和不同燃烧速率对应的告警参数,使得告警设置变得略有难度,如何解此问题将在下一章内容中展开介绍。尽管如此,当所有参数设置得当,该方案依然是最佳选择。基于SLO错误预算预警的方案,最大的优势在于告警发生时,我们可以近似地预估一次告警对于SLO能否达标的影响程度。
通过SLO预警机制,SRE的注意力更多地聚焦在了服务能力和服务水平之上,从疲于应对的单机告警泥淖和深渊中解放出来。在SLO健康度体系下,服务端和客户端基于服务水平和服务能力对齐共识,利用SLO数据做横向通晒,针对高优先级别的SLO告警进行故障复盘,根据复盘内容沉淀专家经验和构建应急知识库。如此循环,通过SLO驱动,应用或系统不断地持续迭代和打磨,服务质量也会显著得到提升。
三、AIOps赋能——SLO和智能化结合
在SLO健康度体系建设中,存在众多基于经验或者规则的设置。例如对应用或系统的月度成功率SLO约定,设置多少认为是合理呢,99%还是99.9%?又如,利用错误预算和燃烧速率设置SLO预警的前提假设是可以把错误量均匀地分摊在时间维度上,然而对于朝夕错误量存在显著差异的场景下,该方案是否依旧有效?SLO预警方面是否可以进一步提效?如何将故障定位和SLO告警结合在一起?SLO预警的设置需要相对专业的知识,如何利用算法降低使用门槛等等。另外,我们希望借助AIOps的能力,在故障应急方面,将SLO健康度体系打造成完整的一站式应急解决方案,赋能到基础设施域内众多的运维场景。
AIOps(Artificial Intelligence for IT Operations,智能运维)将人工智能的能力与运维相结合,通过机器学习的方法提升运维效率。AIOps属于跨领域结合的能力,需要能够理解运维场景、运用机器学习算法、构建一定的工程能力对运维数据进行分析、处理和加工,以此解决或优化传统运维中存在的难题。
经过多年不断地实践总结,我们更愿意把AIOps实践称之为一种范式,即通过结合运维场景和算法能力产出可以支撑运维决策和驱动架构演进的智能。
AIOps赋能SLO,提高了SLO健康度体系在应用场景中的泛化能力和普适性。实践中,围绕SLO健康度体系在故障应急场景下的梳理和抽象,涉及到的能力可以划分为:基础能力、通用能力、定制能力和产品能力。基础能力主要围绕数据面建设铺开;产品能力关注的是用户接入并使用SLO健康度体系时的费力度和易用性,以及通过自动化来提升效率。结合AIOps相关的能力主要体现在通用能力和定制能力建设两个方面,包括对数据的深度挖掘、透视、和下钻等处理,针对分析得到的结果,结合历史沉淀的专家经验以及相关的运维自动化能力,努力逼近无人值守的运维终极理想。
SLO序列本质属于时间序列数据,针对时间序列数据的分析方法,一般分为时间域分析和频率域分析。常见的统计算法、回归算法、神经网络等,都属于时间域分析;频率域主要借助傅里叶变化、小波变换等手段,将时间域数据映射到频率域进行谱成分分析。
所谓合抱之木,生于毫末。再复杂的算法也是由简单的运算和统计规则组合而来,所以掌握基础的分析方法和原理对于理解复杂算法具有显著帮助。具体的,我们罗列了一些常用的数据分析方法。通过均值、众数、以及不同刻度的分位数可以反映出数据集的居中程度;方差、极差、以及四分位差(切边极差)反映了数据集的离散程度;回归模型、时间序列模型、以及神经网络模型可以分析提取时间序列的趋势、季节指数等特征,并用作未来数据的预测;利用傅氏变换、小波变换、序列分解等手段可以检测出时间序列中隐藏的周期和规律性。
构建SLO健康度过程中一个重要的环节就是设定应用或系统的SLO,当SLO设置过低时,目标轻松完成并达标,失去了挑战性,同时也不能有效发现和改进优化系统;当SLO制定过高时,又会造成SLO到期不达标,根据SLA中的约定,执行相应的惩罚机制。所以,如何设置一个合理又富有挑战性的SLO目标值,对于系统的持续演进和迭代至关重要。一般地,经验丰富的专家一开始就可能设定出比较合理的目标值,然而对于新手或者大多数普通用户来说,需要花费大量的时间尝试探索,才能确定出合适的SLO目标值。
针对这个痛点,结合历史数据设计算法自动分析,为每一个应用或系统,计算出其合理的SLO推荐值。其中关键的步骤包括:针对月度成功率SLO数据,对其过往的一个月数据分析一般的统计特性;通过回归模型计算SLO时序的基线水平和基线的波动程度;利用基线计算出残差序列,然后分析残差序列的分布特性,按照其分布特性进行正态性检验,以确保模型的正确性。综合以上步骤的输出,设计算法进行数据融合,最终给出SLO的推荐值。
一般地,对于算法推荐的SLO目标值,最终还是需要业务方、SRE以及研发共同确认后才可生效,根据实际情况,后续也可以加以适当调整。事实上,应用和系统时刻处在不断演进变化的过程中,因而SLO的目标值也会因为业务需要定期或不定期地加以调整。
异常检测是AIOps实践中提及最普遍的能力,无论是学术界还是工业界都有很多相关的文献和实践介绍。之所以被广泛地实践和研究,主要在于其丰富的应用场景和业务需求。从统计视角,异常检测是通过统计学原理发现存在样本集中的离群点或野值。抽象地解释,异常检测过程可以视为将实际观测和预期目标之间的差异和判定阈值做比对,如果差异超出了预期的阈值,则识别为异常,反之,则视为正常。从这个意义出发,我们可以将异常检测描述成两个核心问题:即,预测和检验。
基于统计原理的异常检验算法,一般需要对样本集(残差时间序列)的分布做出假设或定义,构建统计量,然后根据假设检验原理,在一定的显著性水平下,拒绝原假设或者接受备择假设。常见的异常判断准则主要包括:依拉达准则(又称为3 sigma准则,在标准正太分布的数据集中,+/-3sigma的区间可以包含99.7%的分布)、箱体图法(上下四分位刻度结合极差构成,同样,在标准正太分布的数据集中,该区间可以包含99.5%的分布)、Tukey检验、格鲁布斯检验法、迪克逊检验法、以及t检验等方法。判断数据异常与否的关键,在工业场景中主要还是依照经验值,比如假设检验中的显著性水平,亦或是借助大数定理,指定异常数据分布的概率等。
时序的预测问题可以理解为基于t时刻之前的数据来预测t+1时刻或者未来一段时间的趋势。
一般在弱平稳性假定下,对时间序列分析和预测的常见算法,主要是我们罗列的这些种类。预测的本质是希望从历史数据中提取出规律性和确定性,以此来做数据外推和预期管理。
在弱平稳性的假定下,对时间序列分析和预测的常见算法有差分整合移动平均自回归模型(ARIMA)、指数平滑(EMA)、三次指数平滑(Hot Winters)、基于局部加权回归的季节趋势时序分解(STL)、时频变换分析、以及基于人工神经网络原理的循环神经网络(RNN)和长短期记忆网络(LSTM)。预测的本质是希望从历史数据中提取出规律性和确定性,以此来做数据外推和预期管理。AIOps实践中,围绕成本、质量、效率、稳定性等众多场景都需要具备相应的预测能力。
预测+检测模式解决了大部分场景下的异常识别问题,在实践中具有非常出色的泛化能力和检验效果。然而,开展异常检测过程中,也是存在诸多问题和挑战。例如,如何利用异常数据定义异常的程度,1变化到10的异常度和100变化到150的异常程度,前者更加显著还是后者更加显著?很多时候都是取决于业务场景。再比如,从数据角度检验出的异常未必是业务侧需要感知到的告警,异常和告警之间如何转换,是需要基于实际场景来分析和定义。同时,通用的异常检算法,大多未考虑具体场景和专家经验,效果上不如定制化的检测算法,而定制化的算法受限于场景和领域知识的捆绑,其外推和泛化能力比较薄弱。另外,如何有效地异常检测的结果进行采集和评价,以及利用这些反馈数据实现人机回圈的闭环,实践场景中,也是极具挑战性的难题。
除异常检测外,故障定位也是AIOps实践的一个重要方向。应用或系统故障在所难免,如何在预警发生之后快速地定位出故障域和故障根因是后续采取止损措施的关键,其重要性不言而喻。从相对通用的定位思路出发,我们将故障定位归类为:时间相关性定位、依赖相关性定位、空间相关性定位和历史相关性定位。
时间相关性定位关注的重点在于两个或多个事件发生的时间点是否相近和匹配。为了考虑通用性,一般将多个事件(告警事件和运维变更事件等)同时量化为时间序列数据,计算皮尔逊相关系数矩阵(近似理解为归一化的协方差矩阵),因其归一化的结果,非常适合相关性打分。根据场景和专家经验设定阈值,即可判断多个事件在发生时间上的匹配程度。这种方法也可以检验不同时序形态上的相似程度,前提是需要序列长度和时间点对齐。另外,动态时间规整(Dynamic Time Wraping,DTW)方法也可以计算两个时序之间的相似程度,虽然没有对序列长度和时间点对齐的要求,但其结果一般不能归一化,适合做候选结果的排序。
用来检验不同时序形状上的相似程度,一般是需要序列长度和时间点对齐,主要使用皮尔逊相关系数计算,因为计算结果的归一化特点,非常适合做关联打分,另外余弦距离也可以是备选的策略。
依赖相关性定位侧重点在于定位故障链上的传导。复杂系统通常是由数个子模块或依赖组成,往往牵一发而动全身。所以依赖相关性定位需要能够提前梳理好系统的上下游依赖、系统的拓扑结构等知识。例如,Kubernetes作为云原生的事实标准,其复杂程度可见一斑,在如此复杂的系统中想要够快速定位出故障根因,必须弄清楚不同组件之间的调用关系和依赖。一旦系统发生预警,顺着故障可能传播的路径就可以相对容易地定位出问题的根源。
如前面提过的SLD,通过SLF维度扩展,将相关的SLO组合成拓扑依赖关系图,通过故障维度传导定位出故障域。
为了清楚起见,我们展示了基于SLD做故障依赖相关性定位的一份配置片段。在工程实现上,由于SLO数据模型的标准化构建,结合专家经验的梳理,相应的定位配置也非常容易生成,其中dependencies字段描述了该SLO依赖的所有服务和监控指标。
空间相关性定位更多的是从物理拓扑的视角挖掘故障域信息。需要利用应用或系统的元数据描述故障定位时的下钻方向,这些资产数据一般被定义在CMDB或PaaS中,例如机房信息、机柜机架编排信息、网络设备和布线信息、物理服务器和网卡信息,再到具体应用或系统部署信息等。为了更加高效地使用这些资产拓扑信息,在做故障定位时,一般将这些信息存储在图数据中,借助图算法的多样化查询检索能力,快速关联聚合故障实体,以此确定故障域。
历史相关性定位基于对以往的故障数据提炼加工、构建故障知识库,通过异常特征匹配和检索找到故障根因。构建故障知识库是一个精细又漫长的过程,需要垂直领域的专家经验沉淀,将历史的故障信息和原因归类梳理,形成故障手册,算法侧需要将对应故障手册的经验数据抽象和建模,通过特征工程构建知识库。通过历史相关性实施故障定位,本质上属于概率推理,即贝叶斯原理,基于历史数据计算的先验概率(比如,某类运维操作下发生故障的频次等),求解最大化后验概率的条件。这种方案的难点主要在于样本数据(覆盖比较齐全的故障数据)的收集需要很长的时间,以及需要非常专业的领域知识梳理。
AIOps的愿景是希望借助人工智能技术,最终实现运维场景下的无人值守。在运维应急场景中,故障的自动发现、定位,需要能够为决策提供足够充分的输入,以便系统决策采用何种预案执行快速止损。为了实现故障自愈,运维需要具备相当高的自动化水平,这些自动化能力需要专业领域的知识来构建,因而故障自愈可以理解为垂直领域的AIOps实践。自愈的关键在于智能决策,基于定位输出的故障域和根因信息,结合专家经验和离线训练模型,索引到分数最高的恢复预案。实践中,需要在通用定位结果和预案索引之间定制化很多的场景适配逻辑,模型抽象的好坏决定了方案的泛化能力。
在AIOps实践中,像异常检测、故障定位等场景中,为了使得其结果具备可比较性,需要将不同尺度的数据做归一化变换,这种归一化的处理,我们可以理解成一种打分机制。前面我们提到的皮尔逊相关系数可以用作两个时序相关性打分,除此外还有余弦相关系数、Jaccord距离等方法,因为其归一化的输出,皆可被用来做相关性打分。特别地,在故障定位中,我们经常需要为异常发生的时间点和某个运维操作事件的关联性打分,以时间间隔作为自变量,设计经验函数,比如随着时间间隔地增加,分数线性递减、指数递减、或开关式递减等。具体使用何种方法,还是得依据实际场景确定,例如在大多数情况下,我们会选用类似Sigmoid函数的柔性开关式打分方案。
在介绍异常检测的时候我们提到过,在不同场景下,横向对比异常程度是一个比较难的问题,因为可能涉及到业务的敏感性,所以很难给出通用的量化方案。实践中,一种可行的方案是结合异常数据的绝对量和相对量进行异常打分,也能取得不错的效果。另外,在对多维度打分结果做数据融合时,可以采用调和平均分数据综合。通过将尺度不一的数据映射到相同的尺度下,结合经验规则或阈值,显著提高了相关算法的适应性和泛化能力。
四、案例介绍——实践场景和探索
前面两章主要介绍了关于SLO健康度体系建设和AIOps相关的解决方案,本章会重点分享下蚂蚁基础设施团队围绕SLO健康度体系展开的一些实践和探索案例。其中,最主要的探索实践在于,围绕SLO健康度打造出一条应急流水线,将“散装”的AIOps能力(异常发现、故障定位、智能决策、自愈等)串起来,提供了一站式的应急解决方案和指导。
具体地,围绕SLO健康度体系主要介绍三方面的实践场景:SLO质量大盘、K8S SLO健康度体系、以及基于SLO的故障应急流程。SLO质量大盘主要用来汇总基础设施域所有服务SLO的达标情况,同时做横向或跨组织的数据通晒,对齐SLO目标和共识;K8S SLO健康度是基于SLO构建的K8S服务能力可观测性体系,通过对各个组件构建SLO指标,除了直观地反映组件服务能力外,也为持续性运营提供了有效的度量;SLO故障应急流程打通了SLO预警、定位、预案推荐、决策等一系列AIOps能力,将散装的能力组装在一起,再借助钉钉承载各阶段的展示或交互,以此实现掌上运维的应急能力。
像第二章介绍过的,如下展示了实践中一份相对完整的SLO元数据Yaml配置,其中包括SLO的名称定义、模板类型、SLI、统计窗口、目标值,以及使用错误预算配置SLO预警方面的参数设置。
通过解析SLO的Yaml配置,定期采集并计算不同粒度的SLO数据和达标结果,SLO质量大盘按照产品集将相关的服务归类后,把相同产品集下的不同粒度SLO的达标结果直观地呈现出来。如下图表所示,我们提供了月度视角、周视角、以及天视角来展示SLO的结果和达标情况,红色的表格代表了在对应的时间窗口内,该产品集存在部分SLO不达标的情况,点击行首列的产品集名称,即可展开所有SLO达标与否的明细信息和具体SLO数值,以及相关的外链。未来,SLO质量大盘还会和故障定位下钻报告打通,提升大盘的分析能力和交互体验。
数据通晒是SRE常态化的运营机制,通过定期采集并计算不同粒度的SLO数据和达标结果,SLO质量大盘按照产品集将相关的服务归类后,把相同产品集下不同粒度SLO的达标结果直观的呈现出来。
如下图表所示,我们提供了月度视角、周视角、以及天视角来展示SLO的结果和达标情况,红色的表格代表了在对应的时间窗口内,该产品集存在部分SLO不达标的情况,通过颜色区分,直观明了。
同时,在SLO质量大盘我们还和故障定位、下钻报告等运营机制打通,提升了数字大盘的分析能力、交互体验和驱动力。
K8S以声明式的模式提供异步资源交付能力,以Pod创建为例,用户调用APIServer将Deployment的Yaml传递给K8S,经历身份认证、数据校验等一系列逻辑后存储到Etcd中,然后控制器通过将现态和预期终态之间的数量做比对,不间断调和,将元数据和差异数量递交到调度器,通过调度器分配资源和部署编排,最终在目标Node上通过Kubelet拉起Pod。实际上,K8S具体的处理逻辑会比这个描述复杂得多,从SLO体系建设角度,我们重点在于梳理出核心链路和服务水平的关键依赖。
在构建K8S SLO体系时,我们从不同的用户视角出发,制定相应的SLO,这是因为角色不同的用户所关心的能力和侧重点是不尽相同的。直接使用K8S的原生能力,对大多数业务研发来说是有一定的门槛,另外元数据的治理也会异常困难。所以,K8S直接提供服务的用户主要包括像PaaS、研发效能、新计算等一些二方用户。这部分用户主要关注K8S所提供的资源交付能力和访问APIServer的服务水平,因为定义了PaaS级的交付成功率和耗时等SLO;从研发和SRE的视角,除了关注PaaS级的SLO外,也会关心K8S针对单个Pod交付能力相关的SLO,以及Pod运行时的健康度SLO。
站在研发和SRE的视角,我们定义了K8S对Pod新增、升级、删除能力的成功率SLO,以及APIServer成功率、耗时和Pod健康度的SLO。通过这些SLO数据驱动SRE的日常工作和方向,对外数据通晒拉齐和研发的共同目标,基于SLO的告警或质量数据,开展故障复盘和技术共建等。另外,结合核心链路和服务水平的关键依赖,单独从SRE视角,我们还定义了像核心组件相关的SLO、Node健康度SLO、以及交付链路上强依赖的下游系统的SLO等。核心组件方面,比如针对控制器、调度器、Etcd等构建可用性SLO;Node健康度方面,比如故障节点自愈率成功率、故障节点Pod自动迁移成功率等场景的SLO;在K8S强依赖的下游系统方面,以客户端的视角构建如DNS、网络、镜像、存储等服务的延时和可用性SLO。
在构建K8S SLO体系的过程和实践中,我们还沉淀了大量关于SLO预警的故障应急手册和完善的故障管理流程等,这些数据资产和专家经验对于结合人工智能技术赋能运维具有非常大的帮助。
基于SLO健康度体系的故障应急流程是围绕SRE日常工作重点实践和探索的方向,如前面所介绍的,用以构建基于SLO预警、故障定位、预案推荐、自愈等应急能力的流水线模式,通过AIOps对各个环节赋能提效。实践中,随着日益完善的能力建设,这套应急流程已经可以覆盖我们大部分的SLO。同时,借助故障演练平台常态化的演练,可以更加便捷地验证相关能力的有效性,以此提升基础设施侧服务的可用性和稳定性。应急过程最关注时效性,于是我们以钉钉为载体,在移动端设备开发掌上运维能力,以此提升应急效率。
当SLO产生预警时,会根据SLO配置中的告警优先级,选择不同的通知方式进行投递。例如低优先级的告警,只推送告警信息到相应的钉钉应急群;而高优先级的告警除了推送到钉钉应急群外,还会通过电话外呼值班SRE及时关注处理。应急完成后,一个重要的步骤是需要对告警的有效性进行打标,以便日后的统计分析、以及优化。
在SLO预警之后,相应的故障定位流程就会被激活,按照前面介绍的相关性定位方法,以此实现异常下钻和根据归类。一般的,故障定位报告包括:故障域信息(异常SLF和SLD)和根因信息(大部分情况下,故障都是由某个具体的变更引起)。为了更加清晰地呈现出故障报告内容,我们也实现了桌面端的拓扑图展示,通过钉钉消息卡片的链接跳转过去。为了获得更多的定位结果反馈信息,在UI侧增加更全面的反馈选项,这些反馈信息可以帮助定位能力更好地优化和演进。
当完成故障定位的分析后,结合垂直领域的专业知识设计的智能索引,将匹配到的最佳预案自动推送给应急值班SRE,每种预案都对应了相应的故障恢复操作,值班人员通过ChatOps的交互能力或外链跳转完成预案执行。为了证实预案操作后有效与否,最直接的方式是观察SLO告警是否恢复,以及借助异常检测能力自动检验SLO是否恢复到正常水平。
拿到定位结果后,我们会设置大量预案。若仅涉及一些轻量级的恢复操作,可以直接调用。针对略微繁重的操作,则添加一个人工确认的步骤,通过点击钉钉上的传送链接,在其他系统中点击确认,执行预案操作,最后以SLO的指标恢复作为整个故障恢复的衡量标准。
五、总结
SLO主要目的是数字化度量服务质量和服务水平,基于服务相关性能指标的统计分析,对服务水平划分等级目标;通过对服务设定SLO和服务等级公示,有效实现对于服务质量的预期管理、使得服务水平更加透明,公示SLA促使上下游系统之间握手达成共识;在稳定性治理和精细化运维方面,完成从故障驱动到SLO驱动的转变。通过AIOps赋能,建设SLO针对运维场景的应急流水线能力,扩展SLO应用和生态。
当前我们的实践已经基本完成了产品化,将相关的能力和流程沉淀、组装进产品,为用户提供统一的SLO平台服务。后续我们会持续推广和完善,在产品输出、SaaS化和开源方面也会进一步投入。概括总结产品化就是,借助SLO实现服务水平的数字化,让服务质量可观测、可衡量、可通晒,助力服务高质量迭代演进。
其余是一些实践心得方面的感悟和总结,读者自行解读即可。
如果字段的最大可能长度超过255字节,那么长度值可能…
只能说作者太用心了,优秀
感谢详解
一般干个7-8年(即30岁左右),能做到年入40w-50w;有…
230721