什么是SRE?
在刚刚接触SRE时,很多人认为就是Google的一个具备全栈能力的岗位,可以独立解决很多问题的人。
而在深入探究之后发现,SRE确实可以解决很多问题,但问题实在太多了,一个岗位或一个人是很难高效快速的解决的。
比如怎么做容量评估、怎么进行故障演练、怎么能做到服务限流、怎么做到异常熔断、怎么让监控告警更有效等
所以为了解决这些问题,不难看出需要测试、开发、运维以及其他相关岗位人员都得进行合作建设,所以会发现其实可以认为SRE是一套指导建设的体系化方法。
那SRE的目标是什么?
提高稳定性
建设SRE体系的目标是“提高稳定性”
而在SRE中对“提高稳定性”这一目标有着两个衡量的指标
指标 | 释义 |
---|---|
MTBF(Mean Time Between Failure) | 平均故障时间 |
MTTR(Mean Time To Repair) | 故障平均修复时间 |
从他们的释义中可以看出两个指标与系统运行状态关系对应如下
指标 | 系统运行状态 |
---|---|
MTBF | 系统正常运行时 |
MTTR | 系统故障时 |
其实我们对系统稳定性认识就是让系统正常运行状态长时间维持下去,当出现故障时可以快速处理恢复。
所以提升MTBF,降低MTTR
就成为了“提高稳定性”的目标
这让我们在建设SRE做相关工作时,可以依据是否提升MTBF,降低MTTR
去判断工作的有效性
细分目标
有了这个目标之后,问题就来了,MTBF和MTTR两个指标是不是有点太大了,即使可以通过告警、通知或其他手段梳理出其两个指标的时间数据,也不清楚如何具体落实改进阿。
其实MTTR还可以细分4个指标,分别对应系统故障中四个阶段,具体如下
指标 | 释义 | 阶段 |
---|---|---|
MTTI(Mean Time To Identify) | 平均故障发现时间 | 故障发现:故障发生到响应 |
MTTK(Mean Time To Know) | 平均故障认知时间 | 故障定位:根因或是根因范围定位出来为止 |
MTTF(Mean Time To Fix) | 平均故障解决时间 | 故障恢复:采取措施恢复业务 |
MTTV(Mean Time To Verify) | 平均故障修复验证时间 | 故障恢复验证:故障解决后验证业务恢复所用时间 |
而MTBF也可以细分2个阶段,如下
阶段 | 释义 |
---|---|
Pre-MTBF | 故障预防 |
Post-MTBF | 故障改进 |
所以有了具体的阶段分割,我们就可以针对着去做工作,比如参考至赵成老师的SRE稳定性保证规划图
如下
Pre-MTBF(故障预防) | MTTI(故障发现) | MTTK(故障定位) | MTTF&MTTV(故障恢复) | Post-MTBF(故障改进) |
---|---|---|---|---|
故障演练 | AIOps | 日志分析 | 容灾切换 | 故障复盘 |
容量评估 | 舆情感知 | 链路跟踪 | 服务降级 | 改进验收 |
持续交付 | 监控告警 | 根因定位 | 服务限流 | 故障模拟 |
自动化 | 异常熔断 | 混沌工程 | ||
架构设计 | 容量压测 |
在体系建设方面可以分别对应
Pre-MTBF(故障预防) | MTTI(故障发现) | MTTK(故障定位) | MTTF&MTTV(故障恢复) | Post-MTBF(故障改进) |
---|---|---|---|---|
建设演练/On-Call | 应急响应 | 应急响应 | 应急响应 | 复盘改进/On-Call |
在如此清晰明了的阶段化划分,我们建设阶段性工作就非常清晰,有针对性的去做,不怕走错路。
比如Pre-MTBF
时,我们可以做好架构设计提供限流、降级、熔断等Design-for-Failure的服务治理手段,提供快速隔离的条件
而Post-MTBF
时,我们需要做好故障复盘,总结不足以及进行改进措施落地。
在这里呢,也可以借助AIOps能力提高问题定位效率以及告警准确率,降低MTTI
和MTTK
。
辨别故障的基础:合适的SLI,对应的SLO
上述我们知道目标是提升MTBF,降低MTTR
基本是围绕这“故障”这个维度来衡量的,但是系统什么时候才是故障呢?
所以这里我们需要有个判断条件或者说是判断标准,来界定“故障与否”
了解监控系统的同学们会知道“告警”了,就有可能发生“故障”,这里用“有可能”是因为现实场景中通常下是不一定的。
而SRE体系中,有着更好、更准确的衡量标准 SLO(Service Level Objective)
来界定“故障与否”。
而提到了SLO就不得不提其相关的SLI(Service Level Indicator)
先
什么是SLI
建设监控系统的同学会知道,监控中对目标对象进行监控时会有大量的指标,但是很多指标的作用估计微乎其微。
而通过遵循以下两个原则从中脱颖而出让其作用发光发热的指标就是SLI。
- 能标识目标对象是否稳定
- 与用户体验强相关或用户可以明显感知的
所以SLI更能表达出“目标对象稳不稳定”。
VALET选择法
挑选SLI时,很多同学估计会有点摸不着头脑,毕竟仅有原则也很难辨别。
业界也深知这个问题,所以也有一套VALET选择方法依据指标的特质进行分类甄别,指标分类如下所示
类别 | 解释 |
---|---|
Volume(容量) | 服务承诺的最大容量是多少。比如QPS、TPS、会话数、吞吐能力以及连接数等等 |
Availablity(可用性) | 代表服务是否正常,比如请求调用的非5xx状态成功率、任务执行成功情况 |
Latency(时延) | 响应是否足够快,比如时延,但时延的分布符合正态分布,需指定不同的置信区间,有针对性解决。 |
Error(错误率) | 有多少错误率,比如5xx、4xx,也可以自定义状态码 |
Ticket(人工介入) | 是否需要人工介入,比如任务失败需人工介入恢复 |
通过以上类别可以快速区分出SLI,在实际使用场景上是一个非常实用的技巧。
但是这里免不了的就是人工介入,无论是对现有指标的筛选,还是未来接入指标的筛选。
什么是SLO
好,从SLI可以表达“目标对象稳不稳定“这点,我们就可以让SLI + 目标 + 时间维度
就能更精确的表达稳定性现状
比如 1个小时内 90% 时延 <= 80ms
而其就是SLO。
如果以上例子值高于80ms时,就已经代表该SLO已经不达标了,有可能发生故障了。
但是会发现简单的将单独SLO作为“稳定性”的判断标准,未免会陷入到监控领域类似的告警风暴和误报这种困境中。
而现实中衡量业务稳定性时,我们通常会通过多个不同的判断标准和依据来决定业务是否故障
所以我们也可以通过组合多个SLO,采用与运算的方式,来更加精确的表达业务的稳定性
公式如:Availability = SLO1 & SLO2 & SLO3
所以得所有的SLO都达成才能算是达标!
而简单来说SLO的出现让业务的稳定性表达的更加精确、可靠。
关于时间维度
SLO中的时间维度可以分成持续时间
和周期
,用来覆盖以下两种场景
- 时间维度:从故障角度评估
- 请求维度:从成功请求占比评估
时间维度:从故障角度评估
这里可以理解为从SLI已经达不到所设阈值已经持续多长时间的角度,来界定这个SLO是否异常了
比如设定1分钟内请求成功率低于95%持续10分钟就是异常
但是这样的方式在时间细粒度上并不精细
比如出现1分钟内请求成功频率多发低于95%,但并没有持续10分钟,这样其实算是有异常的需要关注的,所以可以利用请求维度进行补充
请求维度:从成功请求占比评估
这里可以理解为在统计周期内SLI是否低于所设阈值,来界定SLO是否异常
比如1天内请求成功率低于95%就是异常
这种方式有效的补充了时间维度的不足,通常就是相辅相成的存在
关于SLO与可用性
可用性通常认识就是几个9,比如 4个9、3个9
但是可用性一直被人诟病的是其数据的准确率问题,而通过SLO组合计算的方式来表达可用性可以保证准确率问题
因为其底层基础就是可表达目标对象是否稳定的SLI + 根据业务特征调整的目标 + 根据业务调整的时间。
通过不断的调整优化改进,可用性的准确率就会持续提升,而且更加贴近业务表现。
关于SLO与故障
从上述表达,SLO可以有效的表达稳定性是否达标,所以通过SLO去设置告警可以有效的告知系统是否处于故障中,
当然通过多个SLO组合后的SLO的告警会更为稳妥,
因为这样不止可以达到告警收敛的效果,也可以让告警更加精确有效,防止狼来了现象。
从这点出发,接下来会介绍的一种量化SLO的数据ErrorBudget更加将这个优势发挥的更加出色
指导工作的量化数据:ErrorBudget
当我们设定好SLO,但是该怎么开展具体工作呢?这时候就没那么直观
所以我们需要有个可量化的数据,可以用于提醒并观测SLO的情况
而SRE中通过反向推导SLO的方式,得出一个量化数据 ErrorBudget(错误预算)就能达到这个效果
什么是ErrorBudget
ErrorBudget,错误预算,可以直白的理解其为“提示你还有多少次犯错的机会”
比如 4周为一周期,应用的请求次数是 4,653,680,反向推导以下SLO得出 ErrorBudget 如下
SLO | ErrorBudget |
---|---|
99.95% 可用性 | 23,268 |
90% 时延 <= 80ms | 465,368 |
99% 时延 <= 200ms | 46,536 |
这样可以将数据转换成计分的形式,更加直观而且感官冲击力更加强。
所以我们可以通过应用 ErrorBudget进行数据的归一化 的方式,更好的来推进稳定性目标的达成
消费 ErrorBudget 数据
稳定性燃尽图
利用ErrorBudget计分形式,使用柱状图形式图表实时展示其状态,当然得设定一个周期建议为4个自然周,周期后数据恢复。
对于特殊的场景,可以适当增大ErrorBudget,可以让其场景合理化,但是还是具体情况具体分析。
故障定级
利用ErrorBudget归一化成次数时,可以利用其消耗数百分比来制定故障等级,这样所有不同的SLO都可以利用同一份规则去做故障定级,达到统一规范的目的。
一般故障等级都会分成P0~P4五个级别,0为最高。
常见的故障等级设定如下
单次消耗比例 | 故障等级 |
---|---|
比例<=5% | P4 |
5%<比例<=20% | P3 |
20%<比例<=30% | P2 |
30%<比例<=50% | P1 |
50%<比例 | P0 |
比如 ErrorBudget为25000,问题产生错误请求超过5000,也就是消耗20%以上既可以定级为P2级以此类推。
具体的等级设定需要根据业务的情况和容忍度去制定。
稳定性共识机制
驾照记分制想必大家都不陌生,在等你发现计分剩下1分时,你开车就会非常的小心,避免犯规导致再教育或驾照吊销。
所以你会发现ErrorBudget也是如此,一旦剩余的数量不多时,你会提高警惕,制定相应的行动措施,来避免稳定性目标SLO不达标。
而如何制定行动措施呢?可以考虑以下两个原则
1. 当剩余预算充足或未消耗之前,对问题的发生要有容忍度
在日常我们会遇到网络抖动或设备瞬时切换导致了极短暂系统不稳定, 这时有极少一部分客户反馈或业务使用时遇到了,结果就被投诉业务不稳定,然后技术人员就立刻放下手头工作去排查问题,后续还要花大量的时间去复盘总结和汇报。
这样消耗了技术人员大量的时间和精力,排查结果对业务没什么大帮助,这样导致的结果会有技术人员手头工作无法完成,也浪费了其他协助人员的时间。
总体来说性价比不高,而且是一个涟漪的扩散影响,这种事情一多了,估计就会引发”海啸“了吧!
现在有了SLO和错误预算判断标准,就有了明确的应对思路:如果预算充足就应该有所容忍不应该被投诉,也不应该高优先级响应。
2. 当剩余预算消耗过快或即将消耗完之前,SRE有权中止和拒绝任何线上变更
这种情形下,可以理解成一个带病的工程师,还在坚持上班工作,但是这时他的工作完成的并不理想,而且有可能会直接倒下的风险
你还忍心给他分配新的任务或让他继续以这样的状态工作下去嘛?
这时应该让他恢复健康,才能继续好好的干下去!
从这点类比可看,团队应该是要优先配合解决影响稳定性的问题,直至问题解决,等到下个周期有了新的错误预算后再恢复正常的变更节奏
注意要点
这两点其实是需要大家都要认可并执行的。因为这里涉及的是多方配合协作问题,有同样的共识才能保证工作协作上的流畅以及高效。
从多方协作这点出发看待,如果要推行该机制是需要”Top-DOwn“自上而下的,比如技术VP或CTO级别。
而且有问题时还可以逐步上升由CTO角度做决策。
基于错误预算的告警
在以往日常工作,经常会收到大量的告警短信,但是其价值非常低,导致的后果就是狼来了,大家都开始对告警产生了不信任。
其实这样的后果是非常严重的,因为极有可能有用的信息被淹没了,导致业务利益受损,多方担责。
当然业界也有解决方案,名为”告警收敛“
常用做法有让相同相似告警合并后在发送给通知人,比如同一集群、同一异常告警
但是这种做法也会充斥着很多信息,无法快速的定位到问题并处理,为什么这样说?
因为只是单纯的将信息合并了,信息量还是没有变化,除非是结合其他手段将信息再提炼计算合并,比如所谓的告警决策树,这样的话会更加精准。
但是这种建设的成本也不低,涉及到收敛的规则设计、对象逻辑层级设计、决策逻辑处理实现等。
而采用基于错误预算告警的方式就能天然的做到告警收敛,因为他是基于业务的SLO的
这也表明我们只关注对稳定性造成影响的告警,而这类告警的出现我们是必须快速响应处理,而且这种告警数量不多
达到收敛效果的同时又非常精准。
简单做法就是将故障定级的阈值进行告警设置,更详细精准的做法会涉及到AIOps领域相关的,
可以从谷歌基于SLO和错误预算的几种告警算法了解
如何衡量SLO是否有效
虽然我们定好的SLO,但是SLO是否有效的反映出业务的稳定性,以及其反推出来的ErrorBudget是否真的能有效指导工作呢?
我们还是需要去进行验证检测,并持续优化的。
这里就需要从三个维度去梳理场景,以及根据三种策略去处理相应情况
哪三个维度?
我们可以从三个维度去评估
维度 | 状态 |
---|---|
SLO达成情况 | 达成(met)或未达标(miss) |
"人肉"投入程度 | 高(high)或低(low) |
用户满意度 | 高(high)或低(low) |
根据这三个维度不同的组装有8种情况
哪三种策略?
而在我们可以用以下三种策略去处理
- 收紧SLO
用户满意度低时,而目标反而达成了,这时我们就要收紧SLO,缩小目标,逐步调整成能反馈出真实情况 - 放宽SLO
用户满意度高时,目标反而没达成,这时我们就可以适当的松绑,将目标调大,也适当增大发布次数,加快业务增长 - 针对问题,持续优化
这里需按情况分析出问题的原因,针对性优化
比如三种维度都符合预期时,增加迭代次数,提升业务生产效能
三种维度都没符合预期时,分析业务特征不断调整优化SLO,落实优化改进措施持续提升
应对情况策略
梳理具体的情况应对表格如下
SLO达成情况 | “人肉”投入程度 | 用户满意度 | 执行策略 |
---|---|---|---|
Met | Low | High | 持续优化:产品用户体验差的问题,所以放宽发布和部署流程并提高速度,或先推迟规划实现,更多专注于提升服务可靠性 |
Met | Low | Low | 收紧SLO |
Met | High | High | 持续优化:如果是告警产生错误的导向,降低敏感度。否则临时放松SLO或减少人工投入、修复产品和提高故障自愈能力。 |
Met | High | Low | 收紧SLO |
Missed | Low | High | 放松SLO |
Missed | Low | Low | 持续优化:告警设置质量不足,需提升告警的敏感度 |
Missed | High | High | 放松SLO |
Missed | High | Low | 持续优化:减少人工投入、修复产品和提升故障自愈能力 |
怎么落地SLO?
前面说了一堆SLO的各种好,那落地的话该怎么入手呢?
其实前面或多或少也说了一点,但是这个篇幅我们就把他揪出来
找出核心链路
实践SRE无非就是服务于业务,所以应从分析业务入手,找出核心点
而虽然业务中应用众多,但是能创造核心价值的是显而易见的,毕竟用户访问量、业务业绩、业务特征从这些角度就可以筛选出整个具有核心价值的链路出来
所以优先从业务角度先整理辨别核心和非核心应用,从而梳理出核心链路,就是我们的指导方针。
其实这里当前并没有很好的自动化手段去整理,毕竟贴近用户的,除了利用机器学习的方式去推断貌似也没什么好解决方法
所以这里会充斥着大量的人肉工作,这里涉及的架构的梳理、业务方的沟通、技术栈的梳理等等。
但是这个付出是值得的,因为这样就会对整个业务有着通盘的理解,以后也更好的开展工作。
梳理应用间关系
当核心链路整理出来后,里面的核心应用与非核心应用都会相应的整理出来,毕竟核心链路就是由核心应用所构成的
而在处理应用与应用直接的关系时,分强弱两种,具体组合情况分类如下
应用角色 | 应用角色 | 关系强弱 |
---|---|---|
核心 | 核心 | 强 |
核心 | 非核心 | 弱 |
非核心 | 非核心 | 弱 |
当我们梳理好关系之后,我们既可以分而治之,对其设定SLO
设定应用SLO
设定应用的SLO,可以遵循四个原则
1. 核心应用SLO要更严格,非核心应用可以放宽
让我们建设更加关注核心业务上
2. 强依赖的核心应用之间SLO要一致:
可以理解他们是同一条道路上的,一旦某个路段出现阻塞时,影响的是整条道路的车辆运行情况。
3. 弱依赖中核心应用对非核心的依赖要有降级、熔断和限流等服务治理手段
主要目的在于降低非核心应用对核心应用的影响,保证用户的最高权益
4. ErrorBudget策略,核心应用的错误预算要共享
如果某个核心ErrorBudget消耗完了,必定是对整个链路有影响的,从而对用户体验上造成影响,这是原则上是要停止链路上所有变更操作的,优先修复。
当然可以根据实际情况放松,比如某个核心应用自身预算充足且不影响核心链路功能,当然这点决策需要非常谨慎。
验证
当然我们设定完,之后都需要验证一把,给出相应的实证,不然就成“自娱自乐”了。
而这里手段,现在所了解到的有两种
- 容量压测
- 混沌工程(Chaos Engineering)
容量压测
容量压测主要作用是对SLO中的Volume类的进行验证,一般容量类的指标有业务的QPS、TPS,
所以会依据这些指标进行容量的进行压力测试,从而暴露依赖关系问题,和各种服务治理措施是否有效。
比如模拟用户访问请求提升TPS并发访问到SLO所设定的数值,然后观察业务是否有影响,原先所设置的的限流降级策略是否生效,达到预期
混沌工程(Chaos Engineering)
混沌工程主要作用是模拟故障发生场景,主动产生线上异常和故障
比如机房断电验证异地双活、打满流量验证网络、写满磁盘或跑满CPU等等操作
混沌工程是非常复杂的系统化工程,因为要线上制造故障,或多或少都要对线上业务造成影响,如果模拟故障造成的真实影响超过预估影响,也要能够快速隔离,并快速恢复正常业务。
看到这句话是不是觉得有点恐怖,貌似跟维稳有点违背阿。
所以混沌工程的实施要非常的谨慎小心。
其中模拟策略必须要经过大量的反复验证,包括异常恢复原实施,确保影响可控之后,经过多方评审或验证才能线上实施。
所以混沌工程并不会在SRE体系初期就会尝试的东西,
必须是在高级阶段,也就是服务治理、容量压测、链路跟踪、监控告警、运维自动化等相对基础和必需的部分非常完善的情况才回去考虑的东西。
混沌工程其实就是从未知中挖掘出问题,从而让业务对自身了解更加清晰,更能保障自己,简单来说就是“在失败中成长”。
什么时候做验证?
我们知道要做验证,但是什么时候做呢?
参考Google的建议,核心就是错误预算充足时可以尝试,尽量避开错误预算不足的时间段。
正常的业务下,完成SLO也不是一件简单的事情,而且也不能给系统稳定性造成风险。
而且得评估故障模拟的影响,比如需要考虑是否损害公司收益?是否损害用户体验?
如果对业务影响很大时,还要将方案粒度细化,分步骤、避免造成不可预估的损失。
所以实际实践中,时间段需要根据业务特征去选择,要考虑故障恢复时间,准备一定要充分,不可大意。
结语
本文为学习赵成老师的SRE实战手册
,所总结得出自己对SRE的理解。
希望对各位有兴趣的同仁们有所帮助。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。