我在刚毕业时,曾负责过部门的持续交付平台的建设,包括功能测试、持续集成、持续发布、监控系统等等,同时也对AWS、腾讯云等云服务生态有所研究。回想那段时间,我磕磕绊绊走了不少弯路,加上比较稚嫩的开发经验,很多事情做的比较蹩脚,不够完美。几年后观察当前行业现状,SRE,DevOps和云原生等概念已逐渐普及,也有了非常多的业内的最佳实践,我觉得有必要对过往的经历做一些总结、思考、与升华。
新开设了专栏《运维体系》,将分享我在DevOps,SRE,AIOps,容器化,云原生等领域的学习和实践心得。
这一次先来聊一聊SRE,文章中的很多内容参考自赵成老师的专栏《SRE实战手册》。
SRE是什么
这几年业界对 SRE 的关注越来越多,大家也几乎达成了共识,Google SRE 就是目前稳定性领域的最佳实践。也可以说,SRE 已经成为稳定性的代名词。
SRE 是一套体系化的方法,我们也只有用全局视角才能更透彻地理解它。
从业界稳定性通用的衡量标准看,有两个非常关键的指标:
- MTBF,Mean Time Between Failure,平均故障时间间隔。
- MTTR,Mean Time To Repair, 故障平均修复时间。
通俗地说,MTBF 指示了系统正常运行的阶段,而 MTTR 则意味着系统故障状态的阶段。
另外,MTTR 可以细分为 4 个指标
- MTTI,Mean Time To Identify,平均故障发现时间。也就是从故障实际发生,到我们真正开始响应的时间,这个过程可能使用户或客服反馈、舆情监控或者是监控告警等。
- MTTK,Mean Time To Know,平均故障认知时间。可以理解为我们常说的平均故障定位时间。这个定位指的是root cause,也就是根因被定位出来。
- MTTF,Mean Time To Fix,平均故障解决时间,也就是从知道了根因在哪里,到我们采取措施恢复业务为止,这里的手段可以是限流、降级、熔断,甚至是重启。
- MTTV,Mean Time To Verify,平均故障修复验证时间,就是故障解决后,我们通过用户反馈、监控指标观察等手段,来确认业务是否真正恢复所用的时间。
读者可结合上面的稳定性保障图来理解每个指标的含义。
如果想提升稳定性,就会有两个方向:提升 MTBF,也就是减少故障发生次数,提升故障发生间隔时长;降低 MTTR,故障不可避免,那就提升故障处理效率,减少故障影响时长。
按照以终为始的思路,SRE 要实现的目标就是提升 MTBF、降低 MTTR,从这个角度出发,我们再次认识到一定要把 SRE 作为一个体系化的工程来建设,而不是单纯在某些技术点上发力。
从实践角度来看,SRE 的力量不能通过一个岗位、一个或几个技术就发挥出来。SRE 是一个体系化工程,它需要协同多个部门、多项技术。
SRE和DevOps的区别
DevOps主要是以驱动价值交付为主,搭建企业内部的功效平台。
SRE主要需要协调多团队合作来提高稳定性。
DevOps核心是做全栈交付,SRE的核心是稳定性保障,关注业务所有活动。
两者的共性是:都使用软件工程解决问题。
DevOps的诞生是由于互联网商业市场竞争加剧,企业为减少试错成本,往往仅推出最小可行产品,产品需要不断且高频的迭代来满足市场需求,抢占市场(产品的迭代是关乎一整条交付链的事),高频的迭代则会促使研发团队使用敏捷模式,敏捷模式下对运维的全栈交付能力要求更严格,则运维必须开启DevOps来实现全栈交付。
因为不断的迭代交付(也就是俗称的变更)是触发故障,非稳定性根源,而互联网产品/服务稳定性缺失会造成用户流失,甚至流到竞争对手那里, 因此关注业务稳定性也变得十分重要,SRE由此诞生。
什么是系统可用性
目前业界有两种衡量系统可用性的方式,一个是时间维度,一个是请求维度,这两个维度的计算公式如下:
- 时间维度:Availability = Uptime / (Uptime + Downtime)
- 请求维度:Availability = Successful request / Total request
时长维度,是从故障角度出发对系统稳定性进行评估。
请求维度,是从成功请求占比的角度出发,对系统的稳定性进行评估。
SLI和SLO
前面谈了系统可用性的两种计算方式,在SRE实践中,通常会选择请求维度来衡量稳定性。
SRE 强调的稳定性,一般不是看单次请求的成功与否,而是看整体情况,所以我们会把成功请求的占比设定为一个可以接受的目标,也就是我们常说的“3 个 9”或“4 个 9”这样的可量化的数字。
这个“确定成功请求条件,设定达成占比目标”的过程,在 SRE 中就是设定稳定性衡量标准的 SLI 和 SLO 的过程。
SLI,Service Level Indicator,服务等级指标,其实就是我们选择哪些指标来衡量我们的稳定性。
SLO,Service Level Objective,服务等级目标,指的就是我们设定的稳定性目标,比如“几个 9”这样的目标。
举个例子,“状态码为非 5xx 的比例”就是 SLI,“大于等于 99.95%”就是 SLO。说得更直接一点,SLO 是 SLI 要达成的目标。
VALET方法
关于如何选择合适的SLI,Google提出了VALET方法。
VALET 是 5 个单词的首字母,分别是 Volume、Availability、Latency、Error 和 Ticket。
- Volume-容量。指服务承诺的最大容量是多少,比如QPS、TPS、吞吐量、会话数和连接数等等。
- Availablity- 可用性。服务是否正常,也可以根据不同的任务状态码来归类。
- Latency- 时延。指响应是否足够快。我们不会直接做所有请求时延的平均,因为整个时延的分布也符合正态分布,所以通常会以类似“90% 请求的时延 <= 80ms,或者 95% 请求的时延 <=120ms ”这样的方式来设定时延 SLO。
- Errors- 错误率。这里除了 5xx 之外,我们还可以把 4xx 列进来,或者增加一些自定义的状态码。
- Tickets- 人工介入。如果一项工作或任务需要人工介入,那说明一定是低效或有问题的。
如何落地SLO
针对核心和非核心应用,以及强弱依赖关系,我们在设定 SLO 时的要求也是不同的,具体来说,可以采取下面 4 个原则。
- 第一,核心应用的 SLO 要更严格,非核心应用可以放宽。 这么做,就是为了确保 SRE 的精力能够更多地关注在核心业务上。
- 第二,强依赖之间的核心应用,SLO 要一致。
- 第三,弱依赖中,核心应用对非核心的依赖,要有降级、熔断和限流等服务治理手段。这样做是为了避免由非核心应用的异常而导致核心应用 SLO 不达标。
- Error Budget 策略,核心应用的错误预算要共享,就是如果某个核心应用错误预算消耗完,SLO 没有达成,那整条链路,原则上是要全部暂停操作的。
- 通过容量压测和混沌工程等手段,对上述过程进行验证,但是一定要在错误预算充足的情况下执行。
故障发现
故障发现就是MTTI的环节,这个环节要做两件事情:第一件事,判断出现的问题是不是故障;第二件事,确定由谁来响应和召集。这两件事,其实就是 SRE 里面提到的 On-Call 机制。
On-Call流程有5个关键步骤。
- 确保关键角色在线。
- 组织 War Room 应急组织。
- 建立合理的呼叫方式。
- 确保资源投入的升级机制。
- 与云厂商联合的 On-Call。
故障处理
MTTR 的另外三个环节,也就是 MTTK、MTTF 和 MTTV 阶段,这三个对应的就是故障诊断、修复与确认。
在故障处理过程中采取的所有手段和行动,一切以恢复业务为最高优先级。
故障处理过程中效率如何,其实取决于三个因素:技术层面的故障隔离手段是否完备;故障处理过程中的指挥体系是否完善,角色分工是否明确;故障处理机制保障是否经过足够的演练。
想要高效地处理故障,并不是说我在技术层面做到完备就可以了,这是一个需要体系化建设和反复磨炼才能最终达成的目标。
故障复盘
SRE 中有一条很重要的原则可以帮到我们,那就是“从故障中学习和提升”,也就是故障复盘。
故障复盘黄金三问:
- 第一问:故障原因有哪些?
- 第二问:我们做什么,怎么做才能确保下次不会再出现类似故障?
- 第三问:当时如果我们做了什么,可以用更短的时间恢复业务?
通过黄金三问,我们找到了故障发生的原因,也明确了做什么可以优化,那接下来就是落地了。要落地,就要明确到底应该由谁来承担主要的改进职责。
“故障是系统运行的常态,正常才是特殊状态”。所以,你无论作为什么角色,一定要以一颗平常心来对待故障,能做到这个程度不容易,这就需要我们更加辩证地看待故障,我们一定要做到鼓励改进,而不是处罚错误。
SRE各个角色如何协作
SRE 并不是一个单纯的岗位定义,它是由多个不同角色组合而成的一个团队。如果从分工来看就是:
SRE = PE + 工具平台开发 + 稳定性平台开发
要把各个角色组织起来,可以通过四个关键步骤
- 项目开工会。
- 业务指标分解及用户模型分析评审会。
- 应急预案评审会。
- 容量压测及复盘会。