要是还没搞明白SLO,你算哪门子SRE呢?

哔哩哔哩技术 2022-08-23 10:01:00

作者介绍

武安闯,哔哩哔哩业务SRE负责人,2016年加入B站,深度参与B站微服务拆分、云原生改造、高可用建设、SRE转型和稳定性体系落地等业务。当前主要关注B站在线业务的SRE稳定性体系建设和推广,对SRE的实践有深入的探索与思考。


一、背景

 

最近几年,Google SRE在国内非常流行。Google SRE方法论中提出了SLO是SRE实践的核心,SLO为服务可靠性设定了一个目标级别,它是可靠性决策的关键因素。那如何选择和计算SLI,如何设置SLO,如何实践落地呢?本文就来讲讲B站SRE在实践SLO时所走的弯路和总结的经验。

 

二、Google SRE中SLO的定义

 

服务水平目标(SLO)指定了服务可靠性的目标水平。由于SLO是做出以数据为依据的可靠性决策的关键,因此它们是SRE实践的核心。

 

上文是Google SRE《站点可靠性手册》中的原文。那为什么需要SLO呢,我们摘取原文中的核心观点:

 

  • 工程师稀缺,需要把时间投入到重要服务的核心问题上

 

  • SLO是做出工作优先级排序和可靠性相关工作的关键

 

  • SRE的核心职责不仅是自动化和处理故障,日常工作都要按照SLO来开展

 

  • 没有SLO,就没有SRE

 

为了采用基于错误预算的可靠性工程方法,同样摘取原文中的核心观点:

 

  • 服务的利益相关方认可此SLO

 

  • 服务正常状态下可以达到SLO的要求

 

  • 组织认可错误预算并在决策中发挥作用

 

  • 有完善的SLO流程

 

否则,SLO合规性成为一个KPI或报告指标,而不是决策制定工具。请记住这句话,因为我们的弯路就走到这里了。

 

三、Google SRE中SLO的实施

 

在《站点可靠性手册》第二章“实施SLO”中,Google详细讲述了如何实施SLO,大致流程如下:

 

1)SLI选择

 

  • 对于请求驱动型服务,SLI一般选择可用性(成功响应的请求比例)、延迟、质量。

 

2)SLI计算

 

  • SLI的计算可以使用应用服务器日志、负载均衡监控、黑盒监控、客户端插件等数据源。

     

  • 一般选择负载均衡监控,因为其代表一个用户请求在整套系统所有模块处理耗时和所有网络传输耗时的总和,且和客户端插件相比,实施成本较低。

 

3)SLO定义

 

  • 基于计算出来的可用性、延迟数据,来定义合适的服务SLO。

 

  • 服务可用性:例如,全年可用性 > = 99.99%。

 

  • 服务延迟:例如,99%的请求<= 200ms,90的请求< 100ms。

 

  • 可以在不同的时间窗口上定义SLO,比如一个月或一个季度。

 

  • 获得关键的利益相关者认可和批准。

 

4)错误预算

 

  • 有了SLI和SLO,时间窗口内的允许失败数就知道了。

 

  • 如果给定时间内错误预算消耗殆尽,要制定错误预算执行策略,如:开发团队专注于可靠性问题,直到系统处于SLO范围内,功能迭代推迟;为了降低风险,冻结生产系统的变更,直到有了错误预算来支持变更。

 

5)记录SLO和错误预算

 

  • SLO的作者,审核人,批准日期,下次审核日期,相关背景。

 

  • 定义和变更有平台、流程、制度、变更事件可回溯。

 

  • SLO的细节:SLI实现、如何计算、如何使用错误预算。

 

  • 错误预算的记录跟上面信息类似。

 

6)仪表盘和报表

 

  • 除了已发布的SLO和错误预算,还需要一个报表和仪表盘来做展示。

 

7)持续改进SLO,提高SLO质量

 

四、我们的SLO实践

 

从上文Google对SLO的介绍中,我们抽象出了关键信息来指导我们的建设。

 

 

 

1、服务分级

 

1)应用:技术视角

 

  • 一个应用对应一个appid,包括前端和后端应用。

 

  • 编码构建后,可独立部署运行。

 

  • 一个业务,会包含多个应用,一般具有相同的命名前缀或关键词。

 

2)业务:产品视角

 

  • 一组网站/APP产品相关功能的聚合。

     

  • 相对独立的业务模块。

     

  • 包含一组相关联的应用。

 

3)等级分级

 

我们分为L0-L3四个级别:

 

  • L0

 

公司级核心业务,一般是公司级基础服务或公司核心业务场景,如APP推荐、视频播放、支付平台及强依赖业务等。

 

  • L1

 

部门级核心业务,一般是L0业务体验中依赖的主要业务、核心的二类业务,如视频播放页的一键三连功能、核心二类业务动态、搜索等。

 

  • L2

 

用户可直接使用的其他业务,如播单、分享、专栏、答题等。

 

  • L3

 

其他后台类业务或对用户体验无影响的业务。

 

4)分级对象

 

  • 先对业务(产品)定级。

     

  • 再对这个业务下的多个应用定级,根据应用所提供的产品功能和故障影响来定,应用等级不超过业务等级。

     

  • 在对此业务中用户所能触达到的API定级,API等级不超过应用等级。

 

5)分级用途

 

  • 基于服务等级,要求核心服务遵守对应技术标准。

     

  • 对不同等级的服务,制定不同的变更流程。

     

  • 报警基于服务等级来做分级。

     

  • 要求服务满足稳定性要求,如具备熔断降级能力,具备同城双活能力等。

 

6)分级运营

 

  • 其他基础平台展示分级数据,基于服务等级定运行策略。

 

  • 基于分级后的技术标准、流程等反推定级准确率提升。

 

 

2、SLO系统

 

1)SLI选择

 

对于在线业务来说,基本都是请求驱动的业务,所以选择可用性、延迟、吞吐。

 

  • 可用性:我们度量了两个指标:错误量、请求成功率。

 

  • 延迟:我们度量了p90和p99两个分位的延迟数据。

 

  • 吞吐:每天的请求总量和单位时间的请求速率。

 

可用性为什么不选择可用时间来度量呢?如果选择时间,一般的做法是在某个时间段内错误率大于多少,则认为这段时间内服务不可用。假如这段时间内某个服务错误率低于阈值但同时有大量用户反馈不可用的话,我们不能掩耳盗铃的认为这段时间服务是可用的。因为无法解决这个问题,所以我们选择了请求成功率。

 

2)SLI模型

 

  • 应用的API是业务功能的直接体现,通过度量API的SLI就能反映出业务某个功能的情况。

     

  • 选择能代表业务核心功能的API,按上面的业务分级模型对这些API定级,一般只度量L0、L1等级的业务和其接口。

     

  • 业务一般都会提供多个功能,比如弹幕的读写,评论的读写,所以业务的SLI是由代表业务功能的多个API SLI数据聚合而成的。

     

  • 对于API,我们度量可用性、延迟、吞吐。

     

  • 对于业务,我们通过聚合API 的SLI,主要度量可用性。

 

3)SLI计算

 

  • 统一标准,使用接入层负载均衡指标。所有面向用户的公网服务都会经过接入层负载均衡,也即SLB(下文统称为SLB)。

 

  • 内网服务东西向调用时通过服务发现直接调用,不过SLB,所以无法用SLB的指标度量。我们认为内网服务的故障最终能在面向用户侧的公网服务中体现出来,所以我们只对面向用户的公网服务做度量。

 

  • API可用性:每分钟计算出API的错误量(HTTP 5XX请求)、总请求量、成功率、分位延迟请求量、吞吐。每天再聚合出一天的错误量、总请求量、成功率、分位延迟请求量、吞吐。有了每天的数据后,可灵活的聚合出API每个季度、半年、全年或某个时间区间的数据。

 

  • 业务可用性:对于业务来说,我们只做错误量、成功率聚合。

 

(a)相同等级的API权重应该是一样的,不同等级的API应该加权;

 

(b)每分钟计算出L0等级API的错误量之和、总请求量之和、总成功率(1 - (错误量之和 / 总请求量之和));

 

(c)每分钟L1等级的API也聚合出相同的数据;

 

(d)每分钟业务可用性 = (L0 API总成功率 * 权重 + L1 API总成功率 * 权重)/ 总权重;

 

(e)有了业务每分钟的可用性后,再聚合出业务一天的可用性,以及灵活的聚合出每个季度、半年、全年或某个时间区间的数据。

 

4)SLO定义

 

  • 只对可用性和延迟做SLO定义,吞吐做SLI仪表盘和报表即可;

 

  • 在API分级时,我们会对API设置一个基于分级的默认SLO,比如L0 API 可用性>= 99.99%,L1 API可用性>= 99.99%,L0 API 99分位延迟<=200ms;

 

  • 在业务分级时,我们会让研发对业务设置一个可用性SLO目标,比如全年可用性>= 99.99%。

 

5)错误预算

 

  • 我们在一开始尝试SLO时,并没有去重点建设错误预算。只是使用了基于服务分级的SLO错误量和可用性报警。

 

6)记录SLO和错误预算

 

我们提供了平台化能力去支持定义SLO时的审核和记录。

 

7)仪表盘和报表

 

  • API仪表盘与报表

 

 

  • 业务仪表盘与报表

 

 

上面一套SLO体系建设完成以后,我们对L0、核心L1业务都做了SLO定义、SLI指标和计算。核心API和业务都具备了SLI报表能力,我们的可用性有了可视化的图表,一切似乎非常美好...但仍存在问题。

 

五、遇到的问题

 

 

1)业务定级

 

  • 业务抽象认知不一,产品范围可大可小。

 

  • L0、核心L1业务在SRE的关注下定级基本准确,但其他业务定级就一言难尽了。

 

2)应用定级

 

  • 应用数量远多于业务,定级难度更高。

 

  • 老应用等级更新延迟于业务重构或产品迭代。

 

  • 除L0、核心L1应用外,其他应用等级准确率低。

 

3)接口定级 

 

  • 接口数量又远多于应用,定级耗时耗力,维护成本高,当时公司还没有API GW平台。

 

  • 同上,接口等级更新延迟于业务重构或产品迭代。

 

4)SLI计算

 

  • 当服务因上下游调用依赖导致请求失败时,API的HTTP CODE可能是200,真实的错误被封到了业务错误码中。SLB作为通用的负载均衡,不会去解析HTTP Body。

 

  • 这就导致一个问题:服务故障了半个小时,但今天的可用性却是100%,可用性SLI指标没受到任何影响,SLO也完全符合要求。

 

  • 如果我们改用应用上报的Metrics(内部使用Prometheus),可以解决此问题。但当应用不可用,无法上报Metrics时,也会获取不到数据,导致SLI数据不准确。

 

  • 我们试过推研发把业务错误码中的系统错误(调用依赖类的系统错误,而非业务逻辑错误)改为HTTP CODE,但成本极高,跟微服务的标准也不相符。

 

5)业务SLI

 

  • 需要筛选出影响业务核心功能的API,这些API的SLI数据再聚合到业务,其他API的SLI数据不影响业务SLI 。

 

  • 业务迭代导致API变更,原API SLI不再代表业务功能,导致业务SLI数据没价值。

 

6)总结一下遇到的问题

 

  • 分级模型过于理想,定级成本高;

 

  • 业务SLI关联关系、API SLI元信息更新不及时,数据准确率低;

 

  • 无法通过一条Metrics计算到的可用性SLI来覆盖业务全部故障场景;

 

  • 部分部门的业务只提供内网服务,不直接对用户,导致没有SLI数据;

 

  • SLI数据好像除了当报表外,也没什么价值。

 

最后压死我们SLO体系的稻草是一个业务需求:把业务的可用性SLI作为业务年度可用性总结报表,替代基于故障时间计算出的业务年度可用性。此需求我们认为是合理的,因为我们度量了业务可用性SLI,那算出的可用性当然可以作为业务年度总结报表来使用了。但我们在实际使用数据时遇到了一个问题:

 

假设某业务正常情况下一天的总请求是24W,此业务某天故障了半个小时,这半个小时在未故障时的请求量是1W,故障时因为用户或链路上的重试导致接入层负载均衡收到的故障请求为2W。

 

  • 基于请求成功率算出的当天业务可用性:( 1 - 2W / ( 24W + 1W) ) * 100% = 92%,假设此业务一年内其他时间日请求不变,每天都是100%可用性,则此业务全年可用性为:1 - (2W / ( 25W + 24W * 364))  = 99.977%

 

  • 基于故障时间算出的当天业务可用性为:( 1 - 0.5 / 24 ) * 100% = 97.916%,假设此业务全年其他时间每天都是100%的可用性,则此业务全年可用性为:( 1 - 0.5 / 24 / 365 ) * 100% = 99.994%

 

可以看出,两种计算方式得出的可用性差距极大。为了解决这个问题,我们想到了一种数据补偿机制:基于故障时段的同环比数据对故障损失数据去重,尽量向故障时间数据靠齐。去重后基于请求成功率数据结果为:

 

  • 忽略重试增加的1W请求量,则当天业务可用性:( 1 - 1W /  24W ) * 100% = 95.833%,假设此业务一年内其他时间日请求不变,每天都是100%可用性,则此业务全年可用性为:1 - (1W / ( 24 * 365))  = 99.988%

 

此方式虽然依旧无法跟基于故障时间的可用性数据对齐,但已经非常接近了,我们认为加上了数据补偿机制之后,统一用这个计算标准的话,业务的可用性SLI是可以作为业务年度可用性报表使用的。想法又一次非常美好...

 

实际运作起来时,我们发现成本太高了。当发生了影响业务核心功能的事故,我们就要对故障数据去重,然后修订故障当天的SLI数据。需要有人去盯着事故报告的损失,跟研发一起核对损失数据,再修订SLI数据.....

 

最终,因为我们执着于提升SLI的准确率,导致整个SLO系统无法运转......此时我们的SLO体系开始停滞和崩溃.....

 

六、反思

 

我们开始反思问题出在了哪里,SLO的价值到底是什么?SLI度量的对象到底是什么?是业务吗,还是应用?Google 基于错误预算做了消耗率报警,我们的SLO除了做报表外好像没啥价值?想清楚这些问题后我们才意识到之前为什么走偏了。

 

1)SLO是可靠性决策的关键因素,但不是非有不可

 

  • 在没有SLO、SLI之前,我想大家的稳定性工作也能分的清楚优先级,比如基于事故复盘来决策高可用工作方向,如服务降级、熔断、中间件高可用、多活容灾等。

 

2)SLO的价值绝对不是报表,而是及时报警,发现影响SLI指标的异常

 

  • SRE中有一章专门讲基于SLO的报警,但在我们的实践中却忽略了这个方向,执着于提升SLI指标的准确率。

 

  • 应用每天都有无数的报警通知,如CPU、内存、磁盘、调用超时、请求错误、请求重试等,产生了大量噪音。但哪些报警会影响到可用性SLI需要SRE和研发关注呢?我想这就是SLO的核心价值之一了。

 

3)错误预算策略是诗与远方

 

  • 如果业务某个季度发生事故,把这个季度的错误预算耗尽,SLO已不符合预期,SRE也不能冻结这个业务的变更。

 

  • 至于调整业务团队的短期目标,从业务迭代转到专注于可靠性问题还是可以的。但这个目标一般是事故驱动达成的共识。

 

  • 如果让国内互联网公司产品迭代停止三个月,我想没有哪个公司会同意。

 

4)SLI度量的核心是业务功能和应用,而不是聚合业务SLI

 

  • API是业务功能的直接体现,通过度量API的SLI就能反映出业务某个功能的情况。

 

  • 业务功能不可能全部枚举出来,接口也不可能全部定级和计算SLI。但应用是有限且标准的,基于应用的Metrics即可算出所有应用的可用性SLI。

 

  • 业务核心功能的SLI通过API SLI已度量出来,是否要聚合成一条代表业务SLI的指标其实并不重要。比如在业务报表页面展示业务多个功能的API SLI数据可能会更直观。

 

  • 业务SLI的核心价值是NOC/技术支持团队在Oncall时的关注指标,或构建业务场景监控时从业务指标到技术指标的下钻串联,更偏向运营层面。

 

以上内容详细介绍了我们在实践SLO体系时的思路,落地方式和遇到的问题。在没彻底理解SLO及其价值的情况下,我们就尝试建设SLO体系,走了很多弯路。反思阶段我们也认清了SLO的价值。下面我们就来讲述我们新认知下的SLO体系建设思路。

 

 

七、业务分级优化

 

1)等级分级

 

还是分为L0-L3四个级别:

 

① L0

 

公司级核心业务,一般是公司级基础服务或公司核心业务场景,如APP推荐、视频播放、支付平台及强依赖业务等,同时需满足:

 

  • 满足DAU > xx W;

 

  • 满足日均营收>  xx W;

 

  • 虽未达到上述要求,但业务属于公司战略级方向。

 

② L1

 

部门级核心业务,一般是L0业务体验中依赖的主要业务、核心的二类业务,如视频播放页的一键三连功能、核心二类业务动态等。

 

③ L2

 

用户可直接使用的其他业务,如播单、分享、专栏等。

 

④ L3

 

其他后台类业务或对用户体验无影响的业务。

 

2)分级模型优化

 

  • 对业务(产品)定级。

 

  • 创建应用(也可叫服务,下文不再区分)时,用户打标这个应用对此业务的重要程度即可:核心、重要、普通。此数据非定级使用。

 

  • 用户只需要在创建业务时做一次业务定级即可。

 

大大简化我们的业务分级模型,不再对应用和API分级,减少大家的心智负担和运维、运营成本。

 

八、SLI选择与计算

 

在线业务常见的微服务调用链路如下:

 

 

从上述链路图中可以看出,可用率、延迟有如下两种指标:

 

  • 应用通过SLB代理时,使用SLB Metrics计算出应用可用率、延迟等SLI:如服务A、服务B。

 

  • 应用Server侧上报指标数据,计算出应用可用率、延迟等SLI:每个微服务都有这个指标上报,适用所有服务。

 

 

上篇中我们有提到,我们只度量了面向用户的公网服务。这导致我们的SLI覆盖率很低,大量的内网应用没有SLI,那SLO报警也就无从做起了。现在补充了HTTP/gRPC Server Metrics后,就能覆盖到所有应用,同时也能覆盖到所有的服务不可用场景。

 

  • 应用访问超时,容器OOM、进程Panic等不可用,会在SLB侧上报错误指标。

 

  • 应用HTTP CODE 200,但因依赖下游服务、读取DB、CACHE失败等系统错误时,会在应用Metrics侧上报错误指标。

 

  • 当应用无法上报Metrics时,可以认为应用已彻底不可用。

 

除可用率、延迟指标外,应用数据层面的新鲜度指标也特别重要。当数据发生延迟时,应用Server侧并不能直接感知到数据是延迟的,要通过其对中间件的Metrics指标来度量。应用对中间件的常见依赖如下图:

 

 

可度量的数据新鲜度指标如下:

 

  • 应用对消息队列服务的写入和消费延迟指标:数据消费延迟会导致用户缓存数据不更新。

     

  • 应用所使用DB的主从同步延迟指标:数据同步延迟会导致用户缓存数据不更新。

     

  • Canal作为数据同步组件的同步延迟指标:数据同步延迟会导致用户缓存数据不更新。

     

  • 多活场景下DTS组件的同步延迟指标:数据同步延迟会导致多机房DB数据不一致。

 

 

1、应用SLI选择与计算

 

1)可用率

 

  • SLB Metrics度量出的应用请求错误量(HTTP 5XX)、请求成功率。

 

  • HTTP/gRPC Server Metrics度量出的应用请求错误量(非业务逻辑错误,如因下游依赖、DB、Cache请求失败导致的应用系统级错误,在我们的微服务框架中,这类错误code一般是-5xx)、请求成功率。

 

2)延迟

 

  • SLB Metrics度量出的应用分位延迟。

 

  • HTTP/gRPC Server Metrics度量出的应用分位延迟。

 

3)新鲜度

 

  • 应用对MQ写入、消费的Metrics来度量消息延迟。

 

  • 应用所使用DB主从同步延迟Metrics。

 

  • 如果使用到Canal组件来更新缓存,那需要度量Canal对DB的消费延迟和对MQ的写入延迟Metrics。

 

  • 多活场景下DTS组件的同步延迟Metrics。

 

上述Metrics以应用维度采集计算存储,在应用视角我们就能看到应用的核心SLI,基于这些SLI指标再来做可用率和新鲜度的SLO报警,报警准确率可以大大提升。

 

假如我们已经度量了评论应用的SLI指标,当触发SLO报警时,我们知道评论应用出问题了,但并不知道是发评论还是读评论功能出问题。为了提高我们SLO的业务精度,我们需要再对业务的核心功能做度量。

 

 

2、业务核心功能SLI选择与计算

 

在上一篇中我们提到:应用的API是业务功能的直接体现,通过度量API的SLI就能反映出业务某个功能的情况。所以我们需要对核心API做SLI度量。

 

1)定义业务功能

 

  • 在SLO系统录入业务对应的业务核心功能,如发送评论、拉取评论。

 

  • 从API GW平台获取API信息,关联到定义的业务功能。

 

2)API SLI选择与计算

 

① 可用率

 

  • SLB Metrics度量出核心API的请求错误量(HTTP 5XX)、请求成功率。

 

  • HTTP/gRPC Server Metrics度量出核心API的请求错误量、请求成功率。

 

② 延迟

 

  • SLB Metrics度量出核心API的分位延迟。

 

  • HTTP/gRPC Server Metrics度量出核心API的分位延迟。

 

③ 吞吐

 

  • 核心API每天的请求总量和单位时间的请求速率。

 

注:吞吐只在核心API上度量,不在应用上度量。因为应用有多个API,包含很多不重要的API,对用户感知很低,度量吞吐意义并不大。

 

④ 新鲜度

 

  • 因为应用Server侧并不能直接感知到数据是延迟的,是通过应用对中间件的Metrics指标来度量,所以API维度并无新鲜度指标。

 

上述Metrics以API维度采集计算存储,这样在业务核心功能视角我们就能看到各种SLI指标情况,以此来了解业务功能目前的运行情况。

 

 

3、业务SLI选择与计算

 

我们已经有了应用SLI、业务核心功能的SLI,难道还不够吗?为何还要建设业务SLI呢?

 

原因如下:

 

  • 业务核心功能SLI是从技术指标计算出来的,如发评论功能的可用率和数据延迟。前面我们有提到错误的请求是指系统依赖导致的错误而非业务逻辑错误,所以此技术指标并不能代表业务逻辑上的成功率。

 

  • 业务SLI的核心价值是NOC/技术支持团队在Oncall时的关注指标,或构建业务场景监控时从业务指标到技术指标的下钻串联,更偏向运营层面。

 

业务指标是需要从业务系统获取,如业务DB或数仓平台。所以只能覆盖公司级核心业务指标,如:

 

  • 点播播放:播放量、在线人数

  • 社区:发送评论量、评论弹幕量

  • 登录:平均登录量、各渠道登录量

 

可以看出,业务SLI其实更侧重于业务吞吐数据指标,有了这个指标后,我们可以做以下两方面的工作建设:

 

  • 重大事故发现:当业务SLI指标异常而触发报警时,可以认为线上发生了重大事故。在很多公司,NOC团队的核心就是关注业务指标的健康度情况。

 

  • 业务观测运营:从业务吞吐指标到业务功能技术指标再到应用技术指标,从上往下构建业务-技术全链路监控能力和可视化能力。

 

业务指标数据收集成本较高,需要按业务系统case by case来建设。我们的思路是让业务部门自建业务数据,再由SLO系统同步、汇聚、清洗后做运营大盘与报警。

 

九、SLO与报警

 

 

1、应用SLO

 

应用维度我们度量了可用率、延迟、新鲜度,可设置对应的SLO如下:

 

  • 可用率 >= 99.99%

  • 响应99分位延迟 <= 1s

  • 数据更新延迟 < = 5min

 

按照应用所属业务的等级,给应用推荐一个默认的SLO,研发和跟SRE沟通后设定。注意:

 

  • 此SLO用于触发SLO报警策略

  • 而非冻结研发变更

 

 

2、业务核心功能SLO

 

业务核心功能维度我们度量了可用率、延迟、吞吐,可设置对应的SLO如下:

 

  • 可用率 >= 99.99%

  • 响应99分为延迟 <= 1s

  • 吞吐不用设置SLO,做仪表盘和报表即可

 

按照所属业务的等级,给代表业务核心功能API同样推荐一个默认的SLO,研发和跟SRE沟通后设定。

 

 

3、业务SLO

 

业务指标本质上是吞吐指标,如播放量、在线人数、评论量等,不需要设置SLO,只用做吞吐下跌的业务报警即可。当触发业务吞吐报警时,一般代表出现了严重事故。

 

 

4、SLO报警

 

虽然我们度量了应用、业务核心功能、业务三个对象的可用率、响应延迟、数据新鲜度、吞吐指标,但各个指标的报警价值并不一样。

 

  • 可用率:用户功能不可用,价值高。

  • 响应延迟:延迟不代表用户功能一定不可用,价值一般。

  • 数据新鲜度:更新延迟代表用户数据延迟,价值高。

  • 吞吐:业务侧的吞吐能发现线上重大事故,价值高。

 

 

监控报警一般情况下是按如下分层建设的:

 

  • 基础设施:机房、网络、设备等。

  • 系统:服务器、存储、硬盘、网卡、虚拟化等。

  • 中间件:DB、Cache、MQ、LB等。

  • 应用:进程内资源、系统资源、QPS、错误、依赖等。

  • 业务:业务核心指标,订单、播放、登录等。

  • 终端:性能、返回码、运营商、地区、APP版本等。

 

对于研发、SRE来说,平时接触最多的应用和业务了,应用和业务侧的报警尤其重要。SLO报警一旦触发就代表影响了用户体验,是准确率最高的报警,可以作为无效报警治理的切入点。Google SRE在《站点可靠性手册》中第五章节也详细讲解了基于可用率SLO的几种报警策略

 

1)目标错误率≥SLO阈值

 

选择一个时间窗口(如10分钟),该窗口内错误率超过SLO阈值时发出报警。例如,如果SLO在30天内为99.9%,则在前10分钟的错误率≥0.1%时发出报警。

 

优点:

 

  • 检测时间良好:总停机时间为0.6秒(10m * 0.1%)。此报警会触发任何威胁SLO的事件,表现出良好的召回率。

 

缺点:

 

  • 精度很低:报警会触发许多不会威胁SLO的事件。10分钟的0.1%错误率会发出报警,而每月错误预算仅消耗0.02%。

 

  • 极端情况下,每天最多可以收到144个报警,即使不需要对此采取任何措施,此服务一个月仍然符合99.9%的SLO。

 

不建议使用此报警策略,精确度太低,每天可能会触发很多报警,逐渐成为噪音,导致狼来了的效果。

 

2)增加报警窗口

 

可以设置当事件消耗了30天错误预算的5%(30d * 5% = 36h)时才收到报警,以提高精度。

 

优点:

 

  • 检测时间仍然很好:完全停机需要2分10秒(30d * 0.1% * 5%)。

 

  • 比前方案1更精确:错误率持续了更长时间,报警可能对应着严重影响错误预算的事件。

 

缺点:

 

  • 非常差的恢复时间:在服务100%不可用的情况下,报警将在2分钟后触发,但在36小时后才恢复。

 

  • 0.1%的错误下,需要36h时才触发报警,此时存在⼤量数据点,计算成本会很高。

 

不建议使用此报警策略,当错误率很低时,报警检测时间太长,接到报警时问题可能已经持续了1天。当服务完全不可用时,2分钟即可报警出来,但恢复要等待36小时,恢复时间太久。

 

3)增加报警持续时间

 

当SLO低于阈值持续一段时间后再触发报警,如10分钟或者1小时。

 

优点:报警精度更高。在触发之前需要持续的低于SLO阈值,意味着报警更可能对应于重大事件。

 

缺点:召回率和检测时间不佳:由于持续时间不随事件严重程度而变化,因此在服务100%中断10分钟或1小时后才会发出报警,0.2%服务中断也会有相同的检测时间。

 

不建议使用此报警策略,因为不管错误率如何,报警检测时间都是一样,报警无基于问题严重程度的分级,对SRE很不友好。

 

4)消耗率报警

 

消耗速率是指相对于SLO,服务消耗错误预算的速度。例如:当错误率是0.1%时,此时消耗速率是1,当错误率是10%时,此时消耗速率是100。下表展示消耗掉一个可用率SLO为99.9%的服务月度错误预算时的时间表。

 

 

可以将报警窗口定为1小时,并设定当消耗掉当月5%的错误预算时发出告警。1小时的窗口消耗掉30天错误预算的5%时,错误预算的消耗率为30d * 24h * 60m * 5% / 60m = 36,报警触发所需的时间为:

 

  • ((1 - SLO)/ 错误率)* 报警窗口 * 消耗率:(( 1 - 99.9% )/ 错误率)* 1h * 36。

 

  • 当错误预算消耗速率是36时,1小时发出报警。

 

  • 当服务完全不可用,错误预算消耗速率是1000,2分10秒发出报警。

 

优点:

 

  • 良好的精确度:此策略选择大部分错误预算消耗时发出报警。更短的时间窗口,计算起来代价较小,检测时间好。

 

缺点:

 

  • 低召回率:消耗速率低于36时永远不会发出报警,假如错误预算消耗率为35,在20.5小时(30d / 35 * 24h)后会消耗掉30天的全部错误预算。

 

  • 服务完全不可用时触发报警需要2分10秒,报警重置时间:58分钟仍然太长。

 

不建议使用此报警策略,因为当错误率 < 3.6%时,永远不会发出报警。

 

5)多次消耗率报警

 

可以使用多个消耗速率和时间窗口来解决上述的问题,来确保当错误率较低时可以发出报警。

 

Google建议设置如下三个报警条件:

 

  • 1小时内消耗月度2%的预算消耗,发出紧急报警。

 

  • 6小时内消耗月度5%的错误预算,发出紧急报警。

 

  • 3天内消耗月度10%的预算,发出故障工单。

 

下表显示了消耗的SLO预算百分比、相应消耗效率和时间窗口:

 

 

优点:

 

  • 能够根据关键值调整监控配置以适应多种情况:错误率高时快速报警;如果错误率很低但持续发生,最终会发出报警。

 

  • 多个消耗速率和时间窗口,报警具有良好的精确度。

 

  • 因为有3天10%错误预算的报警策略,所以有很好的召回率。

 

  • 能够根据错误率的严重程度来选择适合的报警类型。

 

缺点:

 

  • 更多数据、窗口大小和阈值需要管理。

 

  • 由于有3天消耗10%错误预算的报警,当服务完全不可用时,4.3分钟就会触发报警,但需要3天后才恢复。

 

  • 如果所有条件都满足,则会触发多个报警,需要做报警屏蔽。当服务完全不可用时,4.3分钟内10%的预算消耗报警也会触发6小时5%的预算消耗报警、1小时内2%的预算消耗报警。

 

这种报警策略已经具备了很好的精确度和召回率,可以在报警系统里尝试使用这种报警策略。

 

6)多窗口,多消耗率报警

 

可以加一个较短时间窗口,用于在报警和恢复时检查是否仍然达到错误预算消耗速率,从而减少误报。Google建议将短窗口设为长窗口持续时间的1/12。

 

 

如何理解短窗口的作用呢?以1小时消耗月度2%的错误预算为例:

 

  • 假如服务错误率为10%,则错误预算消耗率是100,超过14.4的消耗速率,在43秒(14.4 * 5 / 100 * 60s = 43s)时已经触发了短窗口的条件:5分钟错误预算消耗速率平均值大于14.4。

     

  • 服务故障持续8.6分钟(30d * 24h * 60m * 2% / 100 = 8.64m)时,会消耗掉月度2%的错误预算,触发长窗口的报警阈值:1小时内消耗掉2%的错误预算,此时发出报警。

     

  • 服务故障停止5分钟后,短窗口错误预算消耗速率平均值低于14.4,不会再触发,报警恢复。

     

  • 服务故障停止51.4分钟后,长窗口错误预算消耗平均值速率低于14.4,不会再触发。

 

你可以在前一小时和前五分钟超过14.4倍错误预算消耗速率时发送工单,只有在消耗了2%的错误预算后,才发送报警。5分钟后短窗口不再触发,此时报警恢复时间最佳。

 

优点:

 

  • 灵活的报警框架,允许你根据事件的严重性和组织的要求控制报警类型。

     

  • 良好的精度,与所有固定预算的部分报警方法一样。不错的召回率,因为有三天的窗口。

 

缺点:要指定的参数很多,这可能使报警规则难以管理。

 

这种报警策略大大降低了报警恢复时间,是最合理的报警方式,但增加了报警复杂度,理解起来也有一定的成本。其实方案5也是一种不错的选择,这两种方案都可以实施,具体选哪种报警策略视自己公司的监控系统和报警能力而定。

 

B站目前的SLO报警是基于策略5做了一定调整,不同的服务等级设定了不同的报警窗户和消耗率,大致如下:

 

 

目前我的SLO报警策略也不够精确,缺少低错误预算消耗速率的报警和长时间窗口报警,会漏掉哪些在偷偷消耗错误预算的事件。我们的SLO报警会先向方案5靠齐,再朝着方案6优化。

 

最后总结一下我们开启SLO报警的指标如下:

 

 

十、质量运营

 

有了各个维度的SLI指标和SLO报警后,我们可以很灵活的构建质量运营大盘,如:

 

  • 基于业务SLI构建业务指标大盘。

 

  • 基于业务核心功能SLI构建业务健康度大盘。

 

  • 基于业务和应用的关联关系构建业务应用健康度大盘。

 

  • 业务可用率排名、应用可用率排名。

 

  • 业务大盘到业务核心功能到应用指标的场景监控大盘。

 

总结

 

没有SLO就没有SRE?想必到这里大家对SLO的方法论和实践已经有了深刻的理解。仅度量SLI做可用性报表来给业务带上枷锁是没意义的,SLO的核心价值是定义服务能力,设置SLO报警,及时发现线上问题,优化报警和推动稳定性治理,主动帮业务团队去提升业务质量,合作共赢。

 

>>>>
 

参考资料

 

  • https://mp.weixin.qq.com/s/NJL48oNi8d8CTj1mK_sTVQ

  • https://sre.google/workbook/implementing-slos/

  • https://sre.google/workbook/alerting-on-slos/

 

作者丨SRE团队&基础架构部
来源丨公众号:哔哩哔哩技术(ID:bilibili-TC)
dbaplus社群欢迎广大技术人员投稿,投稿邮箱:editor@dbaplus.cn

活动预告