一、SRE是什么?
最早是由 Google 设定的专门解决系统稳定性的岗位:网站稳定性工程(Site Reliability Engineering),专职负责其超大规模分布式产品的稳定性。而后,SRE慢慢发展成了一系列面向稳定性的,包括技术、管理、流程、组织架构,以及文化建设的最佳实践,并最终被提炼成了一套方法论,广泛流传;
在国内,大家对于SRE还是存在很多疑惑,比如:
- 1、SRE如果不是运维的升级版,那它到底是什么?
- 2、SRE涉及的范围如此之大,到底应该从哪里入手建设呢?
- 3、在稳定性建设方面,有些公司已经做了多年的技术体系建设工作,但为什么还是会故障频发?难道单纯的技术保障还不够吗?
- 4、引入SRE,团队的能力应该怎么提升?组织架构应该怎么匹配?
概念篇
以SLI、SLO作为切入点,一步步建立起SRE稳定性标准
SLI: SLI是经过仔细定义的测量指标,它根据不同系统特点确定要测量什么,SLI的确定是一个非常复杂的过程。SLI确定测量的具体指标,在确定具体指标的时候,需要做到该指标能否准确描述服务质量以及该指标是否可靠。
SLO: SLO(服务等级目标)指定了服务所提供功能的一种期望状态,包含所有能够描述服务应该提供什么样功能的信息。一般描述为:每分钟平均qps > 100k/s;99% 访问延迟 < 500ms;99% 每分钟带宽 > 200MB/s。
实践路径
围绕“故障”这个影响稳定性的核心事件,从故障发现、故障处理、故障复盘三个阶段展开讲解一些具体动作。同时,着眼落地SRE过程中绕不开的组织架构问题,根据过往真实经验和《Google SRE工作手册》尝试设置组织架构和高效的跨团队协作经验
微服务、DevOps等先进概念的引入是公司正确的选择,效率也确实提升了,但是稳定性挑战也跟着来了:在引入了这么多先进的技术和理念之后,这种复杂架构的系统稳定性很难得到保障,怎么办?
这个问题其实不难回答,答案就是 SRE,目前业界也几乎达成了共识,Google SRE 就是目前稳定性领域的最佳实践。Google SRE介绍的大部分内容都是我们每天在做的监控告警、运维自动化、故障处理和复盘等工作,这些就是SRE的一部分。
我们也花了很多精力来做稳定性保障方面的事情,不断的探索在SRE方面的实践,比如:日常稳定性规规范制定,监控、压测、服务治理、客户大促稳定性保障,故障应急和管理,以及组织架构建设(中间件、稳定性、工具平台、运维和安全)等方面,我们也都做了尝试,也积累了一些经验。
落地SRE有哪些问题?
引入微服务以及服务规模快速膨胀之后,系统架构变得异常复杂,很少有人能描述清楚整体的架构是什么样的,导致问题变的更多了,为了解决这些问题,研发和运维都要投入很多的精力,但结果却不尽人意:系统不稳定会被业务团队投诉;然后紧急处理稳定性暴露的技术问题,但是这个时候需求又来了,响应不及时,业务团队又会不满意,事后,还要因为故障责任问题推来推去,对团队氛围影响很大,最终导致”人困马乏”。 上面描述的情况经常发生,要解决这个问题,不是靠一两个SRE岗位或者角色就能够处理掉的,如果是这样的认知,那说明大家对SRE的理解出现了偏差。这只是问题之一,还有一些落地SRE过程中常见的问题如下:
SRE到底是什么?到底能帮我们解决什么问题?
类似的方法论还有DevOps、AIOps,以及混沌工程(Chaos Engineering),它们之间有什么区别?
SRE涉及范围如此之大,我们到底应该从哪里入手建设?
在稳定性技术体系的建设上,我们做了大量的工作,为什么还是故障频发、频频救火?难道单纯的技术保障还不够吗?
每次出故障,我们都觉得响应速度和处理效率已经很高了,但是为什么业务部门和领导仍然不满意,总是指责我们开发和维护的系统不稳定?
每次故障之后,最害怕的就是开复盘会,开着开着就变成了批斗会(这个也还好,但最怕的粉饰太平),有时候问题还没定位清楚,就开始推诿扯皮谁应该背锅了,真不知道开故障复盘会的目的是什么?
引入了SRE,我们团队的能力应该怎么提升?组织架构应该怎么匹配呢?
SRE的要求这么高,作为个体,我应该如何提升自己的能力达到SRE的要求?
问题很多,但总结下来其实就两大类:
理念:SRE到底是什么?我们应该怎么来理解它?有哪些关键点?
实践:到底应该从哪里入手建设SRE?组织架构应该怎么匹配?
而这些众多IT公司都面临的问题,都有对应的解决方案,比如:
构建SRE的切入点:建立共识、统一的稳定性衡量标准,Google SRE 已经给我们提供了很好的标准化手段,也就是SLO。
组织架构如何建设?虽然Google没有明确的答案,但经过多年的互联网从业经验和相关的实践经验,结合一些互联网公司的成功经验,建设组织架构的问题也能解决。
理解SRE,不同的角度理解不同,千差万别,但又好像都有道理;
- 管理者的角度:认为SRE是一个具备全栈能力的岗位,只要有这个岗位就能解决所有稳定性问题;
- 运维人员的角度:认为作为SRE主要是做好监控,做到快速感知、快速定位、快速恢复,是传统运维的升级版,把自动化做好就够了;
- 平台的角度:认为SRE要加强平台容量自动弹性扩缩容;
- 面对这些不同角度的理解,我们不能简单的融合考虑,还是要结合实践来理解SRE,结合我们日常维稳工作的实际情况和参考大部分互联网公司的现状,梳理出来一张图,如下:
画这张图的目的是为了拉齐大家对稳定性工程的认知,以及改善稳定性不是压实提升某项技术能力,更不是某个人、某几个人、某个团队就可以单枪匹马完成的,而是要基于Google SRE的一些理念和方法,在公司内部由技术一号位或者稳定性一号位负责推进并建设成一套稳定性治理体系,能够让体系发挥出力量,来保障业务稳定,告别“case by case,先解决某项技术问题,合规合理性问题后置”的现状。
这里面很多事情依赖运维自动化、DevOps工具链,比如:容量评估要求服务器具备一定的弹性扩缩容能力,还要考虑和监控相结合,这里面就需要研发、运维、可观测团队紧密合作;这些能力之间的相互依赖,就决定了从权责利的角度来看,SRE体系的建设绝对不是某个岗位或者一个具体的部门就能独立完成的,要求团队之间具备高效的协作能力才可以;
从另一个角度来看,上述观点也可以用来度量SRE体系在组织内部的落地情况,如果组织内部,每个角色,团队之间的工作相对还是独立、各自为战,那说明SRE体系还没能很好的建立起来,也就发挥不出它该有的作用;
系统可用性:没有故障,系统就一定是稳定的?
SRE是个体系化的工程,通过体系化的工程维护系统稳定性,具体说来就是提升MTBF(平均故障间隔时长),降低MTTR(平均故障修复时长) 在具体落地之前需要明确下行业对于系统可用性的通用概念:
- 一方面,系统可用性与我们建设SRE的目标强相关,尽量减少系统故障或异常情况的发生,提升系统可用的运行时间占比;
- 另一方面,拉齐认知,系统可用性的概念看似简单,但深入理解和沟通的时候,还是会发现很多不一致的地方,比如:到底怎样才算是可用时长?怎么算是不可用时长?这个标准是什么?除了时间维度,还有其他的衡量维度吗?N个9听起来都很好,那具体说来系统要达到几个9才算是稳定呢?
所以在具体实操SRE之前,我们很有必要先搞清楚基础概念,达成共识,才能事半功倍。
1、衡量系统可用性的2种方式:
1.1、时间维度:Availability = Uptime / (Uptime + Downtime(宕机时间))
一句话概括:从故障角度出发对系统稳定性进行评估;
关键三要素:衡量指标、衡量目标、影响时长;
例子:指标(系统请求状态码),目标(非5xx占比的成功请求数不低于95%),影响时长(持续10分钟);
1.2、请求维度:Availability = Successful request / Total request
一句话概括:从成功请求占比的角度出发,对系统的稳定性进行评估
关键三要素:衡量指标、衡量目标、统计周期;
例子: 指标(系统请求状态码),目标(非5xx占比的成功请求数不低于95%),统计周期(天、周、月、年);
重要经验: 故障一定意味着不稳定,但是不稳定,并不意味着一定有故障发生。
两种衡量方式最终都会落脚到“几个9”的问题上,如下:
2、到底“几个9”才算是稳定呢?
设定“几个9”的系统稳定性目标要考虑的3个因素
2.1、成本因素
理论上9越多越好,但相应付出的成本和代价也就会更高,比如:冗余资源、主备、双活、多活等,这个要根据具体的公司经营状况来考虑ROI了;
2.2、业务容忍度
核心业务(涉及到公司收益的),这种业务容忍度会很低,当然也就意味着9越多越好,对于非核心业务(不会对用户体验造成太大的影响),可能2个9就可以了;
2.3、系统当前的稳定性状况
结合系统的实际情况,定一个合理的标准比定一个更高的标准会更重要,那怎么确定合理呢?
这个需要从系统现状入手,比如系统可用性是低于99%,可以先做到99%,然后在争取到99.5%,在到99.9%,要有个循序渐进的过程,也更容易落地,否则太高的目标导致达不成,反而会打击团队的自信心和积极性;
更多时候,我们应该采用【请求维度】的统计方式,因为SRE关注的稳定性是系统的整体运行状态,而不仅仅只关注故障状态下的稳定性,在系统运行过程中的任何异常,都会被纳入到稳定性的评估范畴中。
SRE切入点:选择SLI(指标),设定SLO(目标)
1、如何选择SLI?
下表指标分层中列举了系统中的常见监控指标,都是日常很熟悉的指标,但是该怎么选呢?
问题切入: 在选指标前置,我们需要先明确两个问题,一般来说,这两个问题解决了,SLI指标也就确认了。
- 我们要衡量谁的稳定性?(找到主体)
- 第一个问题确定后,接下来需要确定的是:这个指标能够表示这个实例是否稳定吗?
原则: 选择SLI指标的两大原则:
- 选择能够表示一个主体是否稳定的指标,如果不是这个主体本身的指标,或者不能表示主体稳定性的,就要排除;
- 针对有用户界面的业务系统,优先选择与用户体验强相关或用户可以明显感知的指标;
基于以上【指标分层】+【问题】+【原则】的方法,我们已经能解决日常工作中90%的SLI设定问题了,但还是有些武断,不过Google也给出了相对科学的方法,一个快速识别SLI指标的方法:VALET,这是5个单词的首字母,分别是:
Volume-容量、Availability-可用性、Latency-时延、Error-错误率、Ticket-人工介入,这5个单词就是我们选择SLI的5个维度。
Volume - 容量:服务承诺的最大容量是多少。比如:QPS、TPS、会话数、连接数等等
Availability - 可用性:代表服务是否正常。比如:请求调用的非5xx状态成功率
Latency - 时延:响应是否足够快。这是一个会直接影响用户访问体验的指标(需要考虑正态分布、置信区间,如90%请求Latency<120ms)
Errors - 错误率:请求返回的5xx、4xx、其他自定义错误码
Tickets - 人工介入:如果一个故障处理需要人工介入,那说明一定是低效或有问题的。比如:数据任务跑失败了。但是无法自动恢复,这时就要人工介入恢复,Tickets 的 SLO可以想象成他的中文含义:门票。一个周期内,门票数量是固定的,比如每月20张,每次人工介入,就消耗一张,如果消耗完了,还需要人工介入,那就是不达标了。
Google提供了一个基于VALET的看板:
2、如何通过SLO计算可用性?
首先,我们应该知道的是SLO就是对应SLI要实现的目标,比如:“几个9”;
但是,我们前面讲到了系统可用性:Availability = Successful request / Total request,然后又深入到了提炼具体的SLI,以及设定对应的SLO,这两者之间是什么关系呢?这涉及到系统整体可用性的两种计算方式:
第一种:直接根据成功的定义来计算(适合对外承诺),存在的问题:对于单次请求的成功与否的判断太过死板,容易错杀误判; Successful = (状态码非 5xx) & (时延 <= 80ms)
第二种:SLO方式计算(适合对内落地) SLO1:99.95% 状态码成功率 SLO2:90% Latency <= 80ms SLO3:99% Latency <= 200ms
直接用公式表示:
Availability = SLO1 & SLO2 & SLO3
实践篇
MTTR耗时占比:传统架构MTTK(定位)占比最大,分布式架构MTTI(发现)占比最大(可通过SLO监控+错误预算机制来判断是否定性为故障)
一、故障发现:建设On-Call机制
1、关键5步法
1.1、确保关键角色在线
这里绝不是值班运维或者sre人员,而是具体业务应用的Owner
1.2、组织War Room 应急组织
建立消防群,当有故障发生时,第一时间通知在消防群通报,这时对应的On-Call同事就要第一时间最高优先级响应和处理)
1.3、建立合理的呼叫方式
在日常工作过程中存在一种情况,谁最熟悉某个系统,谁就容易被7*24小时打扰,比如系统Owner或者架构师,出问题找他们效率最高,所以这些同事就默认为On-Call人员了,但是这样会极大影响这些同事在开发上的精力投入,要么总被打断,要么通宵处理问题,以至于第二天无法正常工作;同时团队中的其他成员也很难得到处理线上故障的机会,从而得到能力上的提升,这种情况下,可以采用“On-Call 手机”,建立手机与所有系统的对应关系,手机在谁手中,谁就承担On-Call的职责 无论是SRE、架构师、一线研发,熟悉某个系统最快最好的方式就是参与On-Call
1.4、确保资源投入的升级机制
这个跟前面几条有一定的相关性,有很多的团队认为On-Call就是设置几个人值班,所有的事情都交给这几个人做;最极端的情况是所有的事情都应该是sre或者运维来完成,但是在分布式架构这种复杂场景下,这种思路是明显不可行的;
这里最核心的一点就是要给到运维和SRE授权,当他发现问题不是自己或现有On-Call人员能解决的时候,他有权调动其他必要的资源投入和上升到自己的主管那里,要求上级主管协调资源投入。必要时还可以上升到更高级别的主管、cto、vp来关注,所以授权非常关键。
1.5、与云厂商联合的On-Call
现在企业上云是大势所趋,绝大情况下,我们对问题和故障的处理,离不开云产品工程师的一起的高效联动,所以我们应该把云产品和云厂商作为我们系统的一部分,而不是单纯的第三方。
二、故障处理:建立有效的故障应急响应机制
原则: 在故障处理的过程中采取的所有手段和行动,一切以恢复业务为最高优先级
大部分的故障复盘的结论有三点:故障隔离手段缺失、关键角色和流程机制缺失、没有演练,这些是大部分公司在面对系统故障时都存在的问题,针对这三种问题,技术建设层面不做过多陈述,重点在如果建立有效的故障应急响应机制;
如果一个问题被定性为故障,那这时我们就要成立War Room,如果在办公期间,大家可以快速聚集到同一个会议室中处理,如果是非办公时间,可以是远程会议形成虚拟War Room,但不管哪种,根本目的是快速同步信息和高效协作;
但是只有一个War Room还是不够的,既然我们把解决故障类比战争,我们就一定要有一套相对应的指挥体系才可以,这个体系里面最重要的就是“关键角色分工”和“沟通机制”。
体系:google的故障指挥体系,是参考了美国消防员在处理1968年森林大火时建立的应急指挥体系;
体系中有三个核心角色:
Incident Commander,故障指挥官,简称IC,这个角色是整个指挥体系的核心,他最重要的职责是组织和协调,而不是执行,下面的所有角色都接受他的指令并严格执行;
Communication Lead,沟通引导,简称CL,负责对内、外的信息搜集及通报,这个角色一般相对固定,有技术支持、QA或者某个SRE来承担都可以,但是要求沟通表达能力要比较好;
Operations Lead,运维指挥,简称OL,负责指挥或指导各种故障预案的执行和业务恢复。
还有一个非常重要的角色,但不在找个体系内,他是:Incident Responders,简称IR,是所有需要参与到故障处理中的各类人员,真正的故障定位和业务恢复都是他们来完成的,比如具体执行的sre、网络和系统运维、业务研发、DBA甚至是QA等;
体系中的流程机制:
按照过程来分,会有如下的一个流程机制:
- 故障发现后,On-Call的SRE或运维,最一开始就是IC,有权召集相应的业务开发或者其他必要资源,快速组织War Room;
- 如果问题和恢复过程非常明确,IC仍然是SRE,就不做转移,由他来指挥每个人要做的具体事情,以优先恢复业务为主;
- 如果问题疑难,影响范围大,这时SRE可以要求更高级别的主管介入,比如SRE主管或者总监等,一般的原则是谁的业务受影响最大,谁来牵头组织。这时SRE要将IC的职责转移给更高级别的主管,如果是全站范围的影响,必要时技术VP或CTO也可以承担IC职责,或者授权给某位总监承担;
体系中的沟通反馈机制:
- 周期性反馈当前进展以及下一步A ction,如果中途有需要马上执行什么操作,也就事先通报,并且要求通报的内容包括对业务和系统的影响是什么,最后由IC决策后再执行,避免忙中出错;
- “没有进展也是进展,也要及时反馈”,没有进展说明当前问题定位或者故障处理遇到阻塞状态,这个时候需要IC决策是否执行一些有损降级,避免故障蔓延;
- 在整个过程中需要减少对执行者的干扰,让执行者能够更聚焦,所以要求团队Leader来搜集反馈并传递IC的指令;
- CL也要搜集信息,CL要做的还不只是传达指令,而是在更大范围内同步汇总后的信息,同时还要整理信息传递给外部联系人;
- 除了快速恢复业务,信息同步的及时和透明也非常关键,并且有些安抚措施必须要快速执行到位,最大程度降低故障引起的PR风险,所以,如果故障的影响范围很广,那我们就要考虑得尽量周全,这时的故障处理在一定程度上,就不单单是技术团队的问题了,而是需要整个公司都投入资源的,而这种需要全公司配合的事情,想要很顺畅的执行,那就一定要在日常做演练,同时一些基本的工具、模版已经建立好,每个角色只要按照模版填写内容即可,可以极大的保证沟通效率;
三、故障复盘:从故障中学习和提升
理想情况下,找到根因,一次性解决所有问题肯定是最高效的,但是,实际情况往往不随人所愿,就是一旦涉及到找根因,那根因往往只能有一个,还特别容易根据找到的根因来定责,导致把原本的寻求根因是什么转变为责任是谁的问题。故障复盘变成了批斗会。
不要找根因,要找原因,因为根因存在口径和理解问题,原因不同;认知层面也要提升:故障原因不止一个,与其争论根因是什么,不如一起看看引起故障的原因有哪些,是不是都有改进的空间;基于这种认知的提升,我们会将所有导致故障和衍生故障发生、业务恢复过程中耗时较长、以及做出错误决策的原因和环节都提炼出来,把这些都算是故障原因,然后针对这些问题和环节制定改进措施;
这些原因和环节可以结合Timeline来做,按照我们之前提到的MTTR(MTTI、MTTK、MTTF、MTTV)先做个分类,然后针对耗时长的环节,反复讨论改进措施是什么;最后确定好责任人和时间点,后续在跟进执行状况;
复盘会上,我们要围绕着三个核心问题展开讨论并给出解决方案,问题如下:
- 故障原因有哪些?
- 我们做什么,怎么做才能确保下次不会在出现类似的故障?
- 当时如果我们做了什么,可以用更短的时间恢复业务?
通过上面这三个问题,我们找到故障发生的原因了,也明确了做什么可以优化,那接下来就要落地了;
要落地,就要明确到底应该由谁来承担主要的改进职责。注意:是改进职责,而不是主要责任;
故障判定的三个原则
- 健壮性原则:这个原则是说每个部件自身要具备一定的自愈能力,比如:主备、集群、限流、降级、重试等;
- 第三方默认无责:这是延伸自上一条,如果使用了第三方服务,我们要默认第三方无责,以此来加强内部的稳定性意识,稳定性一定要做到相对自我可控,而不是完全依赖外部;
- 分段判定原则:一个完整的业务流程中,可能由多个模块或者流程都存在根本原因,所以这个时候就要考虑分段判定了;