gitbook/SRE实战手册/docs/215004.md
2022-09-03 22:05:03 +08:00

161 lines
14 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 03 | SRE切入点选择SLI设定SLO
你好,我是赵成,欢迎回来。
还是先来复习下上节课讲的“系统可用性”的两种计算方式一种是从故障角度出发以时长维度对系统进行稳定性评估另一种是从成功请求占比角度出发以请求维度对系统进行稳定性评估。同时我们还讲到在SRE实践中通常会选择第二种也就是根据成功请求的比例来衡量稳定性
**Availability = Successful request / Total request**
SRE强调的稳定性一般不是看单次请求的成功与否而是看整体情况所以我们会把成功请求的占比设定为一个可以接受的目标也就是我们常说的“3个9”或“4个9”这样的可量化的数字。
那么这个“确定成功请求条件设定达成占比目标”的过程在SRE中就是**设定稳定性衡量标准的SLI和SLO的过程**。
具体来看下这两个概念。SLIService Level Indicator服务等级指标其实就是我们选择哪些指标来衡量我们的稳定性。而SLOService Level Objective服务等级目标指的就是我们设定的稳定性目标比如“几个9”这样的目标。
SLI和SLO这两个概念你一定要牢牢记住接下来我们会反复讲到它们因为落地SRE的第一步其实就是“**选择合适的SLI设定对应的SLO**”。
那我们就正式开始今天的内容。我会带你彻底理解SLI和SLO这两个概念并掌握识别SLI、设定SLO的具体方法。
### SLI和SLO到底是啥
SLI和SLO这两个概念比较有意思看字面意思好像就已经很明白了但是呢仔细一想你会发现它们很抽象。SLI和SLO指的到底是啥呢
接下来我给你讲一个具体的例子,讲完后,你肯定就能理解了。
我们以电商交易系统中的一个核心应用“购物车”为例给它取名叫做trade\_cart。trade\_cart是以请求维度来衡量稳定性的也就是说单次请求如果返回的是非5xx的状态码我们认为该次请求是成功的如果返回的是5xx状态码如我们常见的502或503我们就判断这次请求是失败的。
但是这个状态码只能标识单次请求的场景。我们之前讲过单次的异常与否并不能代表这个应用是否稳定所以我们就要看在一个周期内所有调用次数的成功率是多少以此来确定它是否稳定。比如我们给这个“状态码返回为非5xx的比例”设定一个目标如果大于等于99.95%,我们就认为这个应用是稳定的。
在SRE实践中我们用SLI和SLO来描述。“状态码为非5xx的比例”就是SLI“大于等于99.95%”就是SLO。说得更直接一点SLO是SLI要达成的目标。
通过这个例子你现在是不是已经理解了这两个概念呢。SLI就是我们要监控的指标SLO就是这个指标对应的目标。
好,那接下来我们要解决的问题就很具体了。我们应该选择哪些指标来监控系统的稳定性?指标选好后,对应地怎么定它的目标呢?下面咱们就一一来探索。
#### 系统运行状态指标那么多哪些适合SLI
我们先来讨论怎么选择SLI。要回答怎么选择这个问题我们得先来看看都有哪些可供选择的指标。
在下面这张图中,我列举了系统中常见的监控指标。
![](https://static001.geekbang.org/resource/image/e8/9c/e8a49d7fbfb8df42db84efe44f48f59c.jpg)
这些指标是不是都很熟悉?那该怎么选呢?好像每一个指标都很重要啊!
确实,这些指标都很重要。我们可以通过问自己两个问题来选择。
第一个问题:**我要衡量谁的稳定性?** 也就是先找到稳定性的主体。主体确定后,我们继续问第二问题:**这个指标能够标识这个实例是否稳定吗?** 一般来说这两个问题解决了SLI指标也就确认了。
从我的经验来看,给指标分层非常关键。就像上图那样分层后,再看稳定性主体是属于哪一层的,就可以在这一层里选择适合的指标。但是,你要注意,即便都是应用层的,针对具体的主体,这一层的指标也不是每一个都适合。
根据这几年的实践经验我总结了选择SLI指标的两大原则。
**原则一:选择能够标识一个主体是否稳定的指标,如果不是这个主体本身的指标,或者不能标识主体稳定性的,就要排除在外。**
**原则二:针对电商这类有用户界面的业务系统,优先选择与用户体验强相关或用户可以明显感知的指标。**
还拿我们上面trade\_cart的例子来说主体确定了就是trade\_cart应用层面的请求返回状态码和时延就是很好的指标再来检查下它们能否标识的trade\_cart稳定性毫无疑问这两个指标都可以那么请求返回状态码和时延就可以作为trade\_cart稳定性的SLI指标。
我们换一个指标CPU的使用率这个指标适合吗根据我们刚才说的原则既然我们关注的是trade\_cart的运行状况而CPU是系统层的指标所以在选择应用层SLI的指标时自然会把CPU排除掉。
你可能会说,这样是不是太武断了呀?
我们简单来分析下。假设CPU使用率达到了95%但是只要CPU处理能力足够状态码成功率可能还是保持在4个9时延还是在80ms以内用户体验没有受到影响。另外一种情况假设CPU使用率只有10%但是可能因为网络超时或中断导致大量的请求失败甚至是时延飙升购物车这个应用的运行状态也不一定是正常的。所以结论就是CPU使用率不管是10%还是95%都不能直接反映trade\_cart运行是正常还是异常不适合作为trade\_cart这样的应用运行稳定性的SLI指标。
讲到这里你可能会问哎呀你说的这两个原则我理解了分层也大概能做到但是我还是需要做很多详细的分析才能选择出SLI指标有没有什么更便捷、更快速的方法来帮助我选择啊
不要着急还真有这样一套方法。怎么选SLI我们可以直接借鉴Google的方法VALET。
## 快速识别SLI指标的方法VALET
VALET是5个单词的首字母分别是Volume、Availability、Latency、Error和Ticket。这5个单词就是我们选择SLI指标的5个维度。我们还是结合trade\_cart这个例子一起看一下每个维度具体是什么。
**Volume-容量**
Volume容量是指服务承诺的最大容量是多少。比如一个应用集群的QPS、TPS、会话数以及连接数等等如果我们对日常设定一个目标就是日常的容量SLO对双11这样的大促设定一个目标就是大促SLO。对于数据平台我们要看它的吞吐能力比如每小时能处理的记录数或任务数。
**Availablity-可用性**
Availablity可用性代表服务是否正常。比如我们前面介绍到的请求调用的非5xx状态码成功率就可以归于可用性。对于数据平台我们就看任务的执行成功情况这个也可以根据不同的任务执行状态码来归类。
**Latency-时延**
Latency时延是说响应是否足够快。这是一个会直接影响用户访问体验的指标。对于任务类的作业我们会看每个任务是否在规定时间内完成了。
讲到这里我要延伸下因为通常对于时延这个指标我们不会直接做所有请求时延的平均因为整个时延的分布也符合正态分布所以通常会以类似“90%请求的时延 <= 80ms或者95%请求的时延 <=120ms ”这样的方式来设定时延SLO熟悉数理统计的同学应该知道这个90%或95%我们称之为置信区间。
因为不排除很多请求从业务逻辑层面是不成功的这时业务逻辑的处理时长就会非常短可能10ms或者出现404这样的状态码可能就1ms。从可用性来讲这些请求也算成功但是这样的请求会拉低整个均值。
同时也会出现另一种极端情况就是某几次请求因为各种原因导致时延高了到了500ms但是因为次数所占比例较低数据被平均掉了单纯从平均值来看是没有异常的。但是从实际情况看有少部分用户的体验其实已经非常糟糕了。所以为了识别出这种情况我们就要设定不同的置信区间来找出这样的用户占比有针对性地解决。
**Errors-错误率**
错误率有多少这里除了5xx之外我们还可以把4xx列进来因为前面我们的服务可用性不错但是从业务和体验角度4xx太多用户也是不能接受的。
或者可以增加一些自定义的状态码,看哪些状态是对业务有损的,比如某些热门商品总是缺货,用户登录验证码总是输入错误,这些虽不是系统错误,但从业务角度来看,对用户的体验影响还是比较大的。
**Tickets-人工介入**
是否需要人工介入?如果一项工作或任务需要人工介入,那说明一定是低效或有问题的。举一个我们常见的场景,数据任务跑失败了,但是无法自动恢复,这时就要人工介入恢复;或者超时了,也需要人工介入,来中断任务、重启拉起来跑等等。
Tickets的SLO可以想象成它的中文含义门票。一个周期内门票数量是固定的比如每月20张每次人工介入就消耗一张如果消耗完了还需要人工介入那就是不达标了。
这里我给出一个Google提供的针对类似于我们trade\_cart的一个应用服务基于VALET设计出来的SLO的Dashboard样例结合上面我们介绍的部分就一目了然了。
![](https://static001.geekbang.org/resource/image/fa/f8/fafcdd765f8a58a42fbc75bfca4fd7f8.png "VALET示例图")
VALET我们就讲完了怎么选SLI指标你是不是一下子就清楚了。可以说这是一个我们可以直接复用的工具。上面Google的这张SLO样例图建议你多看几遍看到时候对比思考下自己系统的情况。
## 如何通过SLO计算可用性
到这里我们已经能够根据自己想要保障稳定性的主体来选择合适的SLI指标了也知道SLO就是对应SLI要实现的目标比如“几个9”。
但是,我们前面讲到了系统可用性:
**Availability = Successful request / Total request**
然后又深入到了提炼具体的SLI以及设定对应的SLO那这两者之间是什么关系呢也就是通过SLO应该怎么去计算我们的系统可用性的呢这就涉及到系统整体可用性的两种计算方式。
**第一种,直接根据成功的定义来计算**
也就是我们前面定义一个请求的返回状态码必须是非5xx才算成功同时时延还要低于80ms同时满足这两个条件我们才算是成功的也就是纳入上述公式中Successful request的统计中用公式来表示
**Successful = 状态码非5xx & (时延 <= 80ms**
如果还有其它条件,直接在后面增加做综合判定。
但是这种计算方式存在的问题就是对单次请求的成功与否的判定太过死板容易错杀误判。比如我们前面讲对于时延我们一般会设定置信区间比如90%时延小于等于200ms这样的场景用这种方式就很难体现出来。而且对于状态码成功率和时延成功率的容忍度通常也是也不一样的通过这种方式就不够准确。所以我们就会采取第二种方式。
**第二种方式SLO方式计算**
我们前面讲时延时讲过以下几个SLO这时我们设定稳定性的时候就需要把公式计算方式灵活调整定义一下了。
* SLO199.95% 状态码成功率
* SLO290% Latency <= 80ms
* SLO399% Latency <= 200ms
直接用公式表示:
**Availability = SLO1 & SLO2 & SLO3**
只有当这个三个SLO同时达标时整个系统的稳定性才算达标有一个不达标就不算达标这样就可以很好地将SLO设定的合理性与最终可用性结合了起来。所以通常在SRE实践中我们通常会采用这种设定方式。
如果是这样第一种方式是不是就没有用途了呢当然不是。第一种计算方式也会有它特有的应用场景它通常会被利用在第三方提供的服务承诺中也就是SLA Service Level Agreement。因为对于第三方提供商来说比如云厂商它们要面对的客户群体是非常大的所以很难跟每一家客户都去制定像SLO这么细粒度稳定性目标而且每家客户对稳定性的要求和感知也不同就没法统一。
这种情况下反而是第一种计算方式是相对简单直接的但是这样也决定了SLA的承诺相比SLO肯定也相对比较宽松因为SLA是商业服务承诺如果达不成是要进行赔偿的。关于SLA最直接的参考资料就是各个公有云厂商在官网公开的信息资料你可以找到这些资料作为自己的一个补充学习。
## 总结
讲到这里怎么选择SLI指标、如何制定SLO目标我们就介绍完了。你需要掌握下面三个重点。
1. 对系统相关指标要分层识别出我们要保障稳定性的主体系统、业务或应用是什么然后基于这个主体来选择合适的SLI指标。
2. 不是所有的指标都是适合做SLI指标它一定要能够直接体现和反映主体的稳定性状态。可以优先选择用户或使用者能感受到的体验类指标比如时延、可用性、错误率等。
3. 掌握VALET方法快速选择SLI指标。
## 思考题
最后,给你留一个思考题。
下面我给出一个Google的SLI和SLO设定标准示例内容很直观需要你认真研究一下这个文档结合今天我们所讲的内容请你尝试按照Google提供的规范格式制定一个自己所负责系统的SLO。
Google的SLI和SLO设定模板链接[https://landing.google.com/sre/workbook/chapters/slo-document](https://landing.google.com/sre/workbook/chapters/slo-document)
另外,对今天的内容如果你还有什么疑惑,都可以在留言区提问,也欢迎你把今天的内容分享给身边的朋友,和他一起学习讨论。
我是赵成,我们下节课见。