没有SLO就没有SRE?来看看B站SRE对SLO的实践总结(下)
本期作者
武安闯
哔哩哔哩业务SRE负责人
2016年加入B站,深度参与B站微服务拆分、云原生改造、高可用建设、SRE转型和稳定性体系落地等业务。当前主要关注B站在线业务的SRE稳定性体系建设和推广,对SRE的实践有深入的探索与思考。
01 背景
在上篇文章《没有SLO就没有SRE?来看看B站SRE对SLO的实践总结(上)》中,详细介绍了我们在实践SLO体系时的思路,落地方式和遇到的问题。在没彻底理解SLO及其价值的情况下,我们就尝试建设SLO体系,走了很多弯路。反思阶段我们也认清了SLO的价值。本篇我们就来讲述我们新认知下的SLO体系建设思路。
02 业务分级优化
等级分级
还是分为L0-L3四个级别
L0:公司级核心业务,一般是公司级基础服务或公司核心业务场景,如APP推荐、视频播放、支付平台及强依赖业务等,同时需满足
1.满足DAU > xx W
2.满足日均营收> xx W
3.虽未达到上述要求,但业务属于公司战略级方向
L1:部门级核心业务,一般是L0业务体验中依赖的主要业务、核心的二类业务,如视频播放页的一键三连功能、核心二类业务动态等
L2:用户可直接使用的其他业务,如播单、分享、专栏等
L3:其他后台类业务或对用户体验无影响的业务
分级模型优化
对业务(产品)定级
创建应用(也可叫服务,下文不再区分)时,用户打标这个应用对此业务的重要程度即可:核心、重要、普通。此数据非定级使用
用户只需要在创建业务时做一次业务定级即可
大大简化我们的业务分级模型,不再对应用和API分级,减少大家的心智负担和运维、运营成本。
03 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数据不一致
3.1 应用SLI选择与计算
可用率
SLB Metrics度量出的应用请求错误量(HTTP 5XX)、请求成功率
HTTP/gRPC Server Metrics度量出的应用请求错误量(非业务逻辑错误,如因下游依赖、DB、Cache请求失败导致的应用系统级错误,在我们的微服务框架中,这类错误code一般是-5xx)、请求成功率
延迟
SLB Metrics度量出的应用分位延迟
HTTP/gRPC Server Metrics度量出的应用分位延迟
新鲜度
应用对MQ写入、消费的Metrics来度量消息延迟
应用所使用DB主从同步延迟Metrics
如果使用到Canal组件来更新缓存,那需要度量Canal对DB的消费延迟和对MQ的写入延迟Metrics
多活场景下DTS组件的同步延迟Metrics
上述Metrics以应用维度采集计算存储,在应用视角我们就能看到应用的核心SLI,基于这些SLI指标再来做可用率和新鲜度的SLO报警,报警准确率可以大大提升。
假如我们已经度量了评论应用的SLI指标,当触发SLO报警时,我们知道评论应用出问题了,但并不知道是发评论还是读评论功能出问题。为了提高我们SLO的业务精度,我们需要再对业务的核心功能做度量
3.2 业务核心功能SLI选择与计算
在上一篇中我们提到:应用的API是业务功能的直接体现,通过度量API的SLI就能反映出业务某个功能的情况。所以我们需要对核心API做SLI度量
3.2.1 定义业务功能
在SLO系统录入业务对应的业务核心功能,如发送评论、拉取评论
从API GW平台获取API信息,关联到定义的业务功能
3.2.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.3 业务SLI选择与计算
我们已经有了应用SLI、业务核心功能的SLI,难道还不够吗?为何还要建设业务SLI呢?
原因如下
业务核心功能SLI是从技术指标计算出来的,如发评论功能的可用率和数据延迟。前面我们有提到错误的请求是指系统依赖导致的错误而非业务逻辑错误,所以此技术指标并不能代表业务逻辑上的成功率
业务SLI的核心价值是NOC/技术支持团队在Oncall时的关注指标,或构建业务场景监控时从业务指标到技术指标的下钻串联,更偏向运营层面
业务指标是需要从业务系统获取,如业务DB或数仓平台。所以只能覆盖公司级核心业务指标,如
点播播放:播放量、在线人数
社区:发送评论量、评论弹幕量
登录:平均登录量、各渠道登录量
…
可以看出,业务SLI其实更侧重于业务吞吐数据指标,有了这个指标后,我们可以做以下两方面的工作建设
重大事故发现:当业务SLI指标异常而触发报警时,可以认为线上发生了重大事故。在很多公司,NOC团队的核心就是关注业务指标的健康度情况
业务观测运营:从业务吞吐指标到业务功能技术指标再到应用技术指标,从上往下构建业务-技术全链路监控能力和可视化能力
业务指标数据收集成本较高,需要按业务系统case by case来建设。我们的思路是让业务部门自建业务数据,再由SLO系统同步、汇聚、清洗后做运营大盘与报警
04 SLO与报警
4.1 应用SLO
应用维度我们度量了可用率、延迟、新鲜度,可设置对应的SLO如下
可用率 >= 99.99%
响应99分位延迟 <= 1s
数据更新延迟 < = 5min
按照应用所属业务的等级,给应用推荐一个默认的SLO,研发和跟SRE沟通后设定。注意:
此SLO用于触发SLO报警策略
而非冻结研发变更
4.2 业务核心功能SLO
业务核心功能维度我们度量了可用率、延迟、吞吐,可设置对应的SLO如下
可用率 >= 99.99%
响应99分为延迟 <= 1s
吞吐不用设置SLO,做仪表盘和报表即可
按照所属业务的等级,给代表业务核心功能API同样推荐一个默认的SLO,研发和跟SRE沟通后设定
4.3 业务SLO
业务指标本质上是吞吐指标,如播放量、在线人数、评论量等,不需要设置SLO,只用做吞吐下跌的业务报警即可。当触发业务吞吐报警时,一般代表出现了严重事故。
4.4 SLO报警
虽然我们度量了应用、业务核心功能、业务三个对象的可用率、响应延迟、数据新鲜度、吞吐指标,但各个指标的报警价值并不一样
可用率:用户功能不可用,价值高
响应延迟:延迟不代表用户功能一定不可用,价值一般
数据新鲜度:更新延迟代表用户数据延迟,价值高
吞吐:业务侧的吞吐能发现线上重大事故,价值高
监控报警一般情况下是按如下分层建设的
基础设施:机房、网络、设备等
系统:服务器、存储、硬盘、网卡、虚拟化等
中间件:DB、Cache、MQ、LB等
应用:进程内资源、系统资源、QPS、错误、依赖等
业务:业务核心指标,订单、播放、登录等
终端:性能、返回码、运营商、地区、APP版本等
对于研发、SRE来说,平时接触最多的应用和业务了,应用和业务侧的报警尤其重要。SLO报警一旦触发就代表影响了用户体验,是准确率最高的报警,可以作为无效报警治理的切入点。Google SRE在《站点可靠性手册》中第五章节也详细讲解了基于可用率SLO的几种报警策略
4.4.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
不建议使用此报警策略,精确度太低,每天可能会触发很多报警,逐渐成为噪音,导致狼来了的效果
4.4.2 增加报警窗口
可以设置当事件消耗了30天错误预算的5%(30d * 5% = 36h)时才收到报警,以提高精度
优点:
检测时间仍然很好:完全停机需要2分10秒(30d * 0.1% * 5%)
比前方案1更精确:错误率持续了更长时间,报警可能对应着严重影响错误预算的事件
缺点:
非常差的恢复时间:在服务100%不可用的情况下,报警将在2分钟后触发,但在36小时后才恢复
0.1%的错误下,需要36h时才触发报警,此时存在⼤量数据点,计算成本会很高
不建议使用此报警策略,当错误率很低时,报警检测时间太长,接到报警时问题可能已经持续了1天。当服务完全不可用时,2分钟即可报警出来,但恢复要等待36小时,恢复时间太久
4.4.3 增加报警持续时间
当SLO低于阈值持续一段时间后再触发报警,如10分钟或者1小时
优点:
报警精度更高。在触发之前需要持续的低于SLO阈值,意味着报警更可能对应于重大事件
缺点:
召回率和检测时间不佳:由于持续时间不随事件严重程度而变化,因此在服务100%中断10分钟或1小时后才会发出报警,0.2%服务中断也会有相同的检测时间
不建议使用此报警策略,因为不管错误率如何,报警检测时间都是一样,报警无基于问题严重程度的分级,对SRE很不友好
4.4.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%时,永远不会发出报警
4.4.5 多次消耗率报警
可以使用多个消耗速率和时间窗口来解决上述的问题,来确保当错误率较低时可以发出报警
Google建议设置如下三个报警条件
1小时内消耗月度2%的预算消耗,发出紧急报警
6小时内消耗月度5%的错误预算,发出紧急报警
3天内消耗月度10%的预算,发出故障工单
下表显示了消耗的SLO预算百分比、相应消耗效率和时间窗口
优点:
能够根据关键值调整监控配置以适应多种情况:错误率高时快速报警;如果错误率很低但持续发生,最终会发出报警。
多个消耗速率和时间窗口,报警具有良好的精确度
因为有3天10%错误预算的报警策略,所以有很好的召回率
能够根据错误率的严重程度来选择适合的报警类型
缺点:
更多数据、窗口大小和阈值需要管理
由于有3天消耗10%错误预算的报警,当服务完全不可用时,4.3分钟就会触发报警,但需要3天后才恢复
如果所有条件都满足,则会触发多个报警,需要做报警屏蔽。当服务完全不可用时,4.3分钟内10%的预算消耗报警也会触发6小时5%的预算消耗报警、1小时内2%的预算消耗报警
这种报警策略已经具备了很好的精确度和召回率,可以在报警系统里尝试使用这种报警策略
4.4.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报警的指标如下
05 质量运营
有了各个维度的SLI指标和SLO报警后,我们可以很灵活的构建质量运营大盘,如
基于业务SLI构建业务指标大盘
基于业务核心功能SLI构建业务健康度大盘
基于业务和应用的关联关系构建业务应用健康度大盘
业务可用率排名、应用可用率排名
业务大盘到业务核心功能到应用指标的场景监控大盘
06 总结
没有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/
往期回顾:没有SLO就没有SRE?来看看B站SRE对SLO的实践总结(上)