产品展示 环球体育官方登录入口-首页
环球体育官方登录入口-首页 环球体育官方登录入口-首页
您的位置: 首页>环球体育官方登录入口>公司新闻
环球体育官方登录入口

联系我们contact us

某某机械有限公司
地址:山东省临沂市沂蒙国际财富中心
联系人:王经理
电话:401-234-5678
手机:13800138***

公司新闻

没有SLO就没有SRE?来看看B站SRE对SLO的实践总结

时间:2022-08-28 17:43:14 来源:本站 点击:1次

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  假如服务错误率为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优化。

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

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

  dbaplus社群是围绕Database、BigData、AIOps的企业级专业社群。资深大咖、技术干货,每天精品原创文章推送,每周线上技术分享,每月线下技术沙龙,每季度Gdevops&DAMS行业大会。