《SRE Google运维解密》读书笔记
2021-07-31 13:34:07 23 举报
AI智能生成
《SRE Google运维解密》是谷歌公司发布的一本关于其运维实践的书籍。书中详细阐述了谷歌如何运用软件工程的方法来管理和维护大规模的分布式系统,以及如何通过自动化和数据驱动的方式来提高系统的可靠性、可用性和效率。这本书不仅为读者提供了一种全新的运维理念和方法,而且还分享了许多实用的工具和技术,对于从事运维工作的人员来说具有很高的参考价值。总之,《SRE Google运维解密》是一本值得一读的优秀书籍。
作者其他创作
大纲/内容
01.概述
本书的宗旨:相比最后的软件结果、架构设计而言,真实的设计过程、作者本身的思考经历更有价值。
SRE
SRE,即站点可靠性工程师。如果软件工程职业主要专注于设计和构建软件系统,那么应该有另外一种职业专注于整个软件系统的生命周期管理。从其设计一直到部署,历经不断改进,最后顺利退役。这样一种职业必须具备非常广泛的技能,但是和其他职业的专注点都不同。Google将这个职位称为站点可靠性工程师(SRE,Site Reliability Enginering)。首先,也是最重要的一点,SRE是工程师(enginer)。其次,SRE的关注焦点在于可靠性。SRE并不是无止境地追求完美:当一个系统已经“足够可靠”的时候,SRE通常将精力转而投入到研发新的功能和创造部的产品中。可靠性就像安全性,越早关注越好。
SRE团队通过雇佣软件工程师,创造软件系统来维护系统运行以替代传统模型中的人工操作。
特点
对重复性、手工性的操作有天然的排斥感。
有足够的技术能力快速开发出软件系统以替代手工操作。
倾向于将基本的运维工作全部消除,全力投入在研发任务上。
终极目标是推动整个系统超向于无人化运行,而不仅仅是自动化某些人工流程。SRE团队必须将50%的精力花在真实的开发工作上。
职责
可用性改进
SRE团队的目标不再是“零重故运行”,SRE团队和产品研发团队目标一致,都是在保障业务服务可靠性需求的回时尽可能地加快功能上线速度。
延迟优化
性能优化
效率优化
变更管理
监控
一个需要人工阅读邮件和分析警报来决定目前是否需要采取某种行动的系统从本质上就是错误的。监控系统不应该依赖人来分析警报信息,而是应该由系统自动分析,仅当需要用户执行某种操作时,才需要通知用户。
紧急事务处理
运维手册中记录的调试步骤和分析方法对处理问题的人是不可或缺的。
容量规划与管理
SRE可以通过模型预测用户需求,合理部署和配置可用容量,同时可以改进软件以提升资源使用效率
假设压力测试的结果显示,我们的服务器可以每秒处理大概100个请求(100 QPS)。通过对用户进行的调查显示,我们预计峰值流量会达到3470 QPS,为了处理这些流量,至少需要35个任务实例。但是,由于以下几点考量,我们最终决定至少采用37个实例,也就是N+2模式:
在更新过程中,有一个任务实例将会短暂不可用,只有36个实例可提供服务。
如果另外一个物理服务器同时也出现问题,那么另外一个任务实例也受到影响,只剩35个实例可以对外服务,刚好可以满足峰值要求。
研发与运维的分歧
传统的研发团队和运维团队分歧的焦点主要在软件新版本、新配置的变更的发布速度上。研发部门最关注的是如何能够更快速地构建和发布新功能。运维部门更关注的是如何能在他们值班期间避免发生故障。
由于绝大部分生产故障都是由于部署某项变更导致的——不管是部署新版本,还是修改配置,甚至有时只是因为改变了用户的某些行为造成了负载流量的配比变化而导致故障。这两个部门的目标从本质上来说是互相矛盾的。
02.拥抱风险
不要过分追求稳定
过分追求稳定性限制了新功能的开发速度和将产品交付给用户的速度,并且很大程度地增加了成本,这反过来又减少了一个团队可以提供的新功能的数量。简单地说,用户在一个有着99%可靠性的智能手机上是不能分辨出99.99%和99.999%的服务可靠性的区别的.
合理的可靠性指标
明确地将运维风险与业务风险对应起来。我们会努力提高一项服务的可靠性,但不会超过该服务需要的可靠性。也就是说,当设定了一个可用性目标为99.99%时,我们即使要超过这个目标,也不会超过太多,否则会浪费为系统增加新功能、清理技术债务或者降低运营成本的机会。
正确度量服务风险
主要关注计划外停机这个指标。Google所采用的故障隔离手段使得我们能够保证在任何时候、任何地方对于一个给定的服务,总是可以处理一定的用户流量。(也就是说,我们随时都是部分“在线”的)
通过请求成功率来定义服务可用性。而不是停机时间。
可用性=成功请求数/总的请求数
例如,一个每天可用性目标为9.99%的系统,一天要接受2.5M个请求。它每天出现少于250个错误即可达到预计的可用性目标。
可用性=成功请求数/总的请求数
例如,一个每天可用性目标为9.99%的系统,一天要接受2.5M个请求。它每天出现少于250个错误即可达到预计的可用性目标。
辨别消费者服务的风险容忍度
可用性目标:对于企业用户,我们会设置一个更高的内部可用性目标,以及签署一份如果我们未能达到外部目标的处罚性协议!对于消费用户,我们为YouTube设定了一个相比我们企业的产品更低的可用性目标,因为快速发展更加重要。
收益与成本分析
在为每一项服务确定可用性目标时,可以考虑如下的问题:
构建和运维可用性再多一个“9”的系统,收益会增加多少?
额外的收入是否能够抵消为了达到这一可靠性水平所付出的成本?
基础设施服务的风险容忍度-服务拆分
一种在符合成本效益条件下满足这些竞争性约束的方式就是将基础设施分割成多个服务,在多个独立的服务水平上提供该服务。根据不同客户需求定义服务水平,降低成本。
基础设施服务运维的关键战略就是明确划分服务水平,从而使客户在构建系统时能够进行正确的风险和成本权衡。通过明确划定的服务水平,基础设施提供者其实就是将服务的成本的一部分转移给了用户。以这种方式暴露成本可以促使客户选择既能够满足他们的需求又能够压缩成本的服务水平。
我们可以使用相同的硬件和软件运行多个级别的服务。可以通过调整服务的各种特性提供不同的服务水平,如资源的数量、冗余程度、资源的地理配置,以及基础设施软件的配置。
错误预算的构建
错误预算提供了一个明确的、客观的指标来决定服务在一个单独的季度中能接受多少不可靠性。这个指标在SRE与产品研发部门的谈判中将政治因素排除。
我们的实际做法如下:
产品管理层定义一个SLO,确定一项服务在每个季度预计的正常运行时间。
实际在线时间是通过一个中立的第三方来测算的:我们的监控系统。
这两个数字的差值就是这个季度中剩余的不可靠性预算。
只要测算出的正常在线时间高于SLO,也就是说,只要仍然有剩余的错误预算,就可以发布新的版本。
产品管理层定义一个SLO,确定一项服务在每个季度预计的正常运行时间。
实际在线时间是通过一个中立的第三方来测算的:我们的监控系统。
这两个数字的差值就是这个季度中剩余的不可靠性预算。
只要测算出的正常在线时间高于SLO,也就是说,只要仍然有剩余的错误预算,就可以发布新的版本。
错误预算的好处
它能够激励产品研发和SRE一起找出创新和可靠性之间合理的平衡点。
例如,如果产品研发人员想要在测试上节约时间或者想要提高发布速度并且SRE表示反对时,那么就可以通过错误预算指导决策。当预算剩余很多时,产品研发人员就可以承担更多的风险。如果预算接近耗尽,产品研发人员自身将会推动更多的测试或者放慢发布的速度,因为他们不想冒着用尽预算的风险和拖延他们的程序上线。如果团队无法发布新的功能,他们可以选择降低SLO(从而增加错误预算)来提高创新速度。
03.服务质量目标
服务质量指标(SLI)、服务质量目标(SLO),以及服务质量协议(SLA)。这三项分别是指该服务最重要的一些基础指标、这些指标的预期值,以及当指标不符合预期时的应对计划。
SLI是指服务质量指标(indicator)
该服务的某项服务质量的一个具体量化指标。大部分服务都将请求延迟——处理请求所消耗的时间——作为一个关键SLI。其他常见的SLI包括错误率(请求处理失败的百分比)、系统吞吐量(每秒请求数量)等。
可用性(availability)是另外一个SRE重视的SLI,代表服务可用时间的百分比。对数据存储系统来说,持久性(durability)——数据能够完整保存的时间一也是一个重要指标。
一般来说,四五个具有代表性的指标对系统健康程度的评估和关注就足够了。
SLO是服务质量目标(Objective)
服务的某个SLI的目标值,或者目标范围。SLO的定义是SLI≤目标值,或者范围下限≤SLI≤范围上限。
避免过度可用:SRE保证全球Chubby服务能够达到预定义的SLO,但是同时也会确保服务质量不会大幅超出该SLO。每个季度,如果真实故障没有将可用性指标降低到SLO之下,SRE会有意安排一次可控的故障,将服务停机。
SLA是服务质量协议(Agreement)
指服务与用户之间的一个明确的,或者不明确的协议,描述了在达到或者没有达到SLO之后的后果。这些后果可以是财务方面的——退款或者罚款——也可能是其他类型的。区别SLO和SLA的一个简单方法是问“如果SLO没有达到时,有什么后果?”
如何选择
SLO越少越好:不是所有的产品属性都能用SLO表达,用户的“满意度”就很难。
不要追求完美:刚开始可以以一个松散的目标开始,逐渐收紧。这比一开始制定一个困难的目标,在出现问题时放松要好得多。
一个没有经过精心调校的SLO会导致浪费,某团队可能需要付出很大代价来维护一个过于激进的SLO,而如果SLO过于松散,则会导致产品效果很差。SLO是一个很重要的杠杆:要小心使用。
控制手段
SLI和SLO在决策系统运维时也非常在用:
1.监控并且度量系统的SLI。
2.比较SLI和SLO,以决定是否需要执行操作。
3.如果需要执行操作,则要决定究意什么操作需要被执行,以便满足目标。
4.执行这些操作。
落地实践
起草一份SLA需要业务部门和法务部门选择合适的后果条款。SRE在这个过程由的作用是帮助这些部门理解SLA的SLO达标的概率和困难程度。
04.减少琐事
琐事的定义
一些管理类杂务是必须做的,不应该被归类为琐事:这些是流程开销(overhead)。流程开销通常是指那些和运维产品服务不直接相关的工作,包括团队会议、且标的建立和评估、每周总结以及人力资源的书面工作等。
琐事是运维服务中手动性的,重复性的,可以被自动化的,战术性,没有持久价值的工作。而且,琐事与服务呈线性关系的增长。并不是每件琐事都有以上全部特性
每件琐事都满足下列一个或多个属性
手动性
重复性的
可以被自动化的
战术性的(非战略性的)
没有持久价值
与服务同步线性增长:一个良好管理和设计的服务应该至少可以应对一个数量级的增长,而不需要某些一次性工作(例如增加资源)之外的额外工作。
为什么琐事越少越好
比如,某项服务可能每天都要发出数次警报,并且每个警报都需要大量主观判断的复杂响应。这样的服务从设计上来说就是不佳的,很多复杂性是不必要的。该系统需要被简化、重构以消除掉潜在的故障情况,或者自动处理这些情况。重新设计和重构完成以及完整发布之前,依赖主观判断来应对每一个警报的工作就绝对是琐事。
招聘新的SRE时,我们也会引用上文提及的50%规则,承诺新员工不会专门进行运维工作。我们通过禁止SRE组织或者其中任何小团队退化为专门从事运维工作的组织来实现这个承诺。
什么是工程工作
工程工作(Engineering)是一种新颖的、本质上需要主观判断的工作。它是符合长期战略的,会对你的服务进行长久性的改善的工作。
工程工作通常是有创新性和创造性的,着重通过设计来解决问题,解决方案越通用越好。
工程工作有助于使该团队或是整个SRE组织在维持同等人员配备的情况下接手更大或者更多的服务。
琐事繁多是不是一定不好
已知的和重复性的工作有一种让人平静的功效。完成这些事可以带来一种满足感和快速胜利感。琐事可能是低风险低压力的活动,有些员工甚至喜欢做这种类型的工作。
琐事的存在并不总是坏事,但是每个人都必须清楚,在SRE所扮演的角色中,一定数量的琐事是不可避免的,这其实是任何工程类工作都具有的特点。
Google确实会奖励做那些脏活累适的人,但是仅仅是该工作是不可避免,没有人可以通过不停地做脏活累活满足自己的职业发展。
如果SRE过于愿意承担琐事,研发同事就更倾向于加入更多的琐事,有时候甚至将本来应该由研发团队承担的运维工作转给SRE来承担。
05.分布式系统的监控
白盒监控(white-box monitoring)
依靠系统内部暴露的一些性能指标进行监控。包括日志分析、Java虚拟机提供的监控接口,或者一个列出内部统计数据的HTTP接口进行监控。
白盒监控则大量依赖对系统内部信息的检测,如系统日志、抓取提供指标信息的HTTP节点等。白盒监控系统因此可以检测到即将发生的问题及那些重试所掩盖的问题等。
黑盒监控(black-box monitoring)
通过测试某种外部用户可见的系统行为进行监控。
黑盒监控是面向现象的,代表了目前正在发生的——而非预测会发生的——问题,即“系统现在有故障”。
为什么要监控
监控一个系统有多个原因,包括如下几项。
①分析长期趋势
②跨时间范围的比较,或者是观察实验组与控制组之间的区别
③报警
④构建监控台页面(大屏显示)
⑤临时性的回溯分析(也就是在线调试)
①分析长期趋势
②跨时间范围的比较,或者是观察实验组与控制组之间的区别
③报警
④构建监控台页面(大屏显示)
⑤临时性的回溯分析(也就是在线调试)
防止警报风暴
当紧急警报出现得太频繁时,员工会进入“狼来了”效应,怀疑警报的有效性甚至忽略该警报,有的时候在警告过多的时候甚至会忽略掉真实发生的故障。
由于无效信息太多,分析和修复可能会变慢,故障时间也会相应延长。高效的警报系统应该提供足够的信息,并且误报率非常。
对监控系统设置合理预期
Google趋向于使用简单和快速的监控系统配合高效的工具进行事后分析。我们会避免任何“魔法”系统——例如试图自动学习阀值或者自动检测故障原因的系统。
由于Google基础设施的重构速度很快,很少有团队会在监控系统中维护复杂的依赖关系。
从现象到根源问题的定位速度可以更快,尤其是在一个不断改变的系统中。监控系统中最重要的一点就是整个“生产故障,人工处理紧急警报,简单定位和深入调试”过程必须要保持非常简单,必须能被团队中任何一个人所理解。
现象与原因
监控系统应该解决两个问题:什么东西出故障了,以及为什么出故障。
“什么东西出故壁了”即为现象(symptom)
“为什么”则代表了原因(可能只是中间原因,并不是根源问题)
4个黄金指标
监控系统的4个黄金指标分别是延迟、流量、错误和饱和度(saturation)。
延迟
服务处理某个请求所需要的时间。这里区分成功请求和失败请求很重要。
流量
对Web服务器来说,该指标通常是每秒HTTP请求数量,同时可能按请求类型分类(静态请求与动态请求)。针对音频流媒体系统来说,这个指标可能是网络I/O速率,或者并发会话数量。针对键值对存储系统来说,指标可能是每秒交易数量,或每秒的读取操作数量。
错误
请求失败的速率,要么是显式失败(例如HTTP 500),要么是隐式失败(例如HTTP 200回复中包含了错误内容),或者是策略原因导致的失败(例如,如果要求回复在1s内发出,任何超过1s的请求就都是失败请求)。当协议内部的错误代码无法表达全部的失败情况时,可以利用其他信息,如内部协议,来跟踪一部分特定故障情况。
饱和度
服务容量有多“满”。通常是系统中目前最为受限的某种资源的某个具体指标的度量。(在内存受限的系统中,即为内存;在I/O受限的系统中,即为IO)。这里要注意,很多系统在达到10%利用率之前性能会严重下降,增加一个利用率目标也是很重要的。
关于长尾问题
长尾与平均:区分平均值的“慢”和长尾值的“慢”的一个最简单办法是将请求按延迟分组计数(可以用来制作直方图):延迟为0-10ms之间的请求数量有多少,30-100ms之间,100-300ms之间等。
度量指标时采用合适的精度
系统的不同部分应该以不同的精度进行度量。
高频率收集、存储、分析可能成本很高。可以通过一些内部采样机制外部汇总的方式降低成本。
简化,直到不能再简化
复杂是没有止境的。就像任何其他软件系统一样,监控系统可能会变得过于复杂,以至于经常出现问题,变更非常困难,维护起来难度很大。
少即是多
那些最能反映真实故障的规则应该越简单越好,可预测性强,非常可靠。
那些不常用的数据收集、汇总,以及警报配置应该定时删除(某些SRE团队的标准是一个季度没有用到一次即将其删除)。
收集到的信息,但是没有暴露给任何监控台,或者被任何警报规则使用的应该定时删除。
和其他软件工程的理念一样,保持系统相对独立,清晰简单,松耦合的接口是更好的策略(例如,利用Web API来收集性能数据,采用一种可以持续很久不变的简单数据格式)。
将上述理念整合起来
应对紧急的一些深层次的理念?
每当收到紧急警报时,应该立即需要我进行基操作。每天只能进入紧急状态几次,太多就会导致“狼来了”效应。
每个紧急警报都应该是可以具体操作的。
每个紧急警报的回复都应该需要基种智力分析过程。如果基个紧急警报只是需要一个固定的机械动作,那么它就不应该成为紧急警报。
每个紧急警报都应该是关于某个新问题的,不应该彼此重叠。
长跑
按季度进行紧急警报的频率统计,保证每个决策者都理解目前的运维压力,以及系统的健康状况。
长远来看,要建立一个成功的on-call轮值体系,以及构建一个稳定的产品需要选择那些正在发生和即将发生的问题来进行报警,设置一个可以实际达到的合理目标,保证监控系统可以支持快速的问题定位与检测
06.自动化系统的演进
自动化是双刃剑
对于SRE而言,自动化是一种力量倍增器,但不是万能药。当然,对力量的倍增并不能改变力量用在哪的准确性:草率地进行自动化可能在解决问题的同时产生出其他问题。
一致性
重复性的工作:一致性地执行范围明确、步骤已知的程序一是自动化的首要价值。
平台性
通过正确地设计和实现,自动化的系统可以提供一个可以扩展的、广泛适用的,甚至可能带来额外收益的平台。
修复速度快
构建一个在问题发生之后马上应对的自动化系统,对干降低系统的总成本非常有利,前提是该系统足够大。
行动速度快
在基础设施中,SRE自动化系统应用广泛。这是因为人类通常不能像机器一样快速反应。
节省时间
一旦你用自动化封装了某个任务,任何人都可以执行它们。因此,时间的节省适用于该自动化适用的所有人。将某个操作与具体操作的人解耦合是很有效的。
API
Google为那些供应商没有提供API的系统构建了自己的API。虽然购买某一特定任务的软件会更便宜,但我们仍倾向于选择自主开发,因为这样可以产生具有长期价值的API。我们花了很多时间来克服自动化系统管理的各种障碍,随后坚决地进行了自动化系统管理本身的开发。
Perl这种完整的语言提供了POSIX级别的接口,理论上在系统API层面上提供了一个基本上是无限的扩展范围。而Chef和Puppet则提供了一些“开箱即用”的抽象层,通过对这些抽象层的操作可以直接操作服务或者其他高级对象。
自动化演进路径
1)没有自动化
手动将数据库主进程在多个位置之间转移。
2)外部维护的系统特定的自动化系统
SRE在他或她的主目录中保存了一份故障转移脚本。
3)外部维护的通用的自动化系统
SRE将数据库支持添加到了每个人都在使用的“通用故障转移”脚本中。
4)内部维护的系统特定的自动化
数据库自己发布故障转移脚本。
5)不需要任何自动化的系统
数据库注意到问题发生,在无须人工干预的情况下进行故障转移。
自动化所有东西
自动化带来良性循环:
自动化的主要好处是,我们有更多的空闲时间花在改进基础设施的其他部分上。这些改进有一个连锁效应:节省的时间越多,优化和自动化其他烦琐工作的时间就越多。
自动化应该对那些隐含的“安全”信号非常小心。
幂等地解决不一致情况
从“Python单元测试发现错误置”到“Python代码修复错误配置”的演进能够使我们更快解决这些问题。
单元测试已经能够指出被检查的集群中哪个测试失败,我们就给每个测试增加了一个修复程序。
专业化倾向
自动化程序的不同体现在三个方面:
能力,即准确性。
延迟,开始执行后,执行所有步骤需要多久。
相关性,自动化所涵盖的实际流程比例。
最可用的工具通常是由那些每天使用它们的人写成的。
解耦子系统,引入API,最大限度地减少副作用等
07.发布工程
自服务模型
发布过程可以自动化到基本不需要工程师干预,很多项目都是利用我们的自动构建工具和部署工具自动构建、自动发布的,发布过程是真正的自动化的,工程师仅仅在发生问题时才会进行干预。
追求速度
有些团队每小时构建一次,然后在所有可用的构建版本中选择某个版本进行发布。选择过程是基于测试结果与所包含的功能列表共同得出的。还有的团队采用一种“测试通过即发布”(Push On Green)的发布模型,也就是说,部署每个通过所有测试的版本。
一致可重复
构建工具必须确保一致性和可重复性。如果两个工程师试图在两台不同的机器上基于同一个源代码版本构建同一个产品,构建结果应该是相同的。
密闭性
构建过程都是密闭的(hermetic),意味着它们不受构建机器上安装的第三方类库或者其他软件工具所影响。
摘樱桃
当修复某个运行在生产环境中的软件的Bug,而需要重新构建之前的一个发布版本时,一般来说是比较复杂的。Google按照之前的源代码版本,加入一些后来提交的改动来构建新的发布来解决这个问题,这种方式被称为摘樱桃(cherry picking)。
构建工具自身也是放置在与被构建的程序同一个源代码仓库之中的。因此,如果要对上个月构建的某个项目进行chery picking,仍然会用当时的编译器版本,而不会用到这个月新的编译器版本,这样可以保证编译器功能的一致性。
安全性
多层安全和访问控制机制可以确保在发布过程中只有指定的人才能执行指定的操作。
引入时间点
团队应该在开发流程开始时就留出一定资源进行发布工程工作。尽早采用最佳实践和最佳流程可以降低成本,以免未来重新改动这些系统。
08.简单化
在系统的灵活性和稳定性上维持平衡
乏味是一种美德
为了最小化意外复杂度,SRE团队应该:
在他们所负责的系统中引入意外复杂度时,及时提出抗议。
不断地努力消除正在接手的和已经负责运维的系统的复杂度。
清理无用代码
SRE推崇保证所有的代码都有必须存在的目的的实践。例如,审查代码以确保它确实符合商业目标,定期删除无用代码,并且在各级测试中增加代码膨胀检测。
当我们感觉到增加新功能需求时,应该保持保守的态度。我曾经做过的一些最令人满意的编码工作就是删除了数千行已经没用的代码。
最小API
书写一个明确的、最小的API是管理软件系统管理简单性必要的部分。我们向API消费者提供的方法和参数越少,这些API就越容易理解,我们就能用更多的精力去尽可能地完善这些方法。在软件工程上,少就是多!一个很小的,很简单的API通常也是一个对问题深刻理解的标志。
API版本化
通过将API版本化,可以允许开发人员继续使用它们的系统所依赖的版本,以更安全和深思熟虑的方法升级到新的版本。这样不必要求整个系统的每一次功能增加或改进都需要全面的生产更新,整个系统中的更新节奏可以不同。
一个设计良好的分布式系统是由一系列合作者组成的,每一个合作者都具有明确的、良好定义的范围。
发布简单化
如果同时发布100个不相关的系统更改,而系统性能变差了,我们需要花费大量时间和努力来定位哪些改变影响了系统性能,以及它们是怎样影响的。如果发布是按更小的批次进行的,我们就可以更有信心地进行更快的发布,因为每个变更在系统中的影响可以独立理解。
软件的简单性是可靠性的前提条件
09.on-call轮值
在on-cal值班过程中,值班人员必须保证可以随时响应紧急问题,不管是在工作时间,还是在非工作时间。在IT行业里,on-call任务一般是由专门的运维团队(Ops)进行的,主要目标是保障他们所运维的服务维持正常运转。
on-call 工程师的一天
一旦接收到报警信息,工程师必须确认(ack),on-call工程师必须能够及时定位问题,并且尝试解决问题。必要的话,on-call工程师可以联系其他团队,或者升级(escalate)请求支援。
很多团队同时有主on-call人和副on-call人值班,主副分工每个团队都各有不同。
数量上保持平衡
至少将SRE团队50%的时间花在软件工程上。在其余时间中,不超过25%的时间用来on-call,另外25%的时间用来处理其他运维工作。
多地团队相比之下有以下两点优势:
长时间执行夜间任务对人的健康不利。多地团队可以利用“日出而作,日落而息”(Follow the sun)的轮值制度使整个团队避免夜间值班。
2.通过限制一个团队在on-call轮值制度中的人员数量,可保障每个工程师对生产环境的熟悉程度。
多地团队增加了沟通和合作的成本。因此,是否将当地团队转为多地团队应该慎重地决定,仔细考虑两种模式的成本,业务系统的重要性,以及每个系统的业务压力。
质量上保持平衡
处理任何一个生产环境事件,包括事件根源分析、事件处理,以及事后总结等,至少需要6个小时。因此,我们认为,每12个小时的轮值周期最多只能产生两个紧急事件。
补贴措施
针对工作时间之外的on-call工作应给予合理的补贴。不同的组织团队用不同的方式进行补贴。Google提供年假或者现金补贴,同时按一定程度的工资比例作为上限。
复杂系统问题处理思维
在面临挑战时,一个人会主动或非主动(潜意识)地选择下列两种处理方法之一:
依赖直觉,自动化、快速行动。
理性、专注、有意识地进行认知类活动。
当处理复杂系统问题时,第二种行事方式是更好的,可能会产生更好的处理生具,以及计划更周全的执行过程。
直觉很可能是错误的
直觉一般都不是基于明确的数据支持的。因此,在处理问题的过程中,on-call工程师很有可能由于凭直觉去解释问题产生的原因而浪费宝贵的时间。
快速反应主要是由习惯而产生的,习惯性的快速反应的动作后果一般都没有经过详细考虑,这可能会将灾难扩大。
在应急事件处理过程中,最理想的方法是这样的:在有足够数据支撑的时候按步骤解决问题,同时不停地审视和验证目前所有的假设。
处理流程与规范
清晰的问题升级路线。
清晰定义的应急事件处理步骤。
无指责,对事不对人的文化氛围。
效率提升-Web工具开发
Google内部开发使用了一个Web工具,可自动化大部分操作。比如提供方便的职责交接流程,以及保留对外状态更新公告的历史等。利用这些工具,on-call工程师可以专注于解决问题,而不是在格式化公告邮件,或者是同时更新多个对外沟通渠道上浪费时间。
书写事后报告
SRE团队必须在大型应急事件发生之后书写事后报告,详细记录所有事件发生的时间线。这些事后报告都是对事不对人的,为日后系统性地分析问题产生的原因提供了宝贵数据。犯错误是不可避免的,软件系统应该提供足够的自动化工具和检查来减少人为犯错误的可能性。
运维压力过大
错误的监控系统配置常常是导致运维压力过大的原因。报警策略必须跟服务的SLO目标一致,每条报警信息必须是可实际操作的(指收到报警后有明确的动作需要执行)。一个每小时都触发的低优先级报警会严重影响on-cal工程师的生产力。
降低系统运维压力可能需要改变复杂的系统架构,甚至需要几个季度的时间来完成。在这种情况下,SRE团队不应该承担全部运维压力,而是应该和研发团队协商,将某些或者全部报警信息转交给研发组处理。采用这样的临时措施,SRE才能有时间和精力与开发团队共同将系统运维压力降低,以便重新由SRE独立运维。
奸诈的敌人一—运维压力不够
SRE团队运维压力不够也是一个不良现象。长时间不操作生产环境会导致自信心问题,包括自信心太强以及自信心不够。这些现象只有在下一次发生问题时,才会显现出来。
10.有效的故障排查手段
值得警惕的是,理解一个系统应该如何工作并不能使人成为专家。只能靠调查系统为何不能正常工作才行。
提高新手的拍错能力
1.对通用的故障排查过程的理解(不依靠任何特定系统)
2.对发生故障的系统的足够了解
从理论上讲,我们将故障排查过程定义为反复采用‘’假设-排除‘’手段的过程:针对某系统的一些观察结果和对该系统运行机制的理论认知,我们不断提出一个造成系统问题的假设,进而针对这些假设进行测试和排除。
造成低效的故障排查过程的原因
通常集中在定位(triage)、检查和诊断环节上,主要由于对系统不够了解而导致。
关注了错误的系统现象,或者错误地理解了系统现象的含义。这样会在错误的方向上浪费时间。
不能正确修改系统的配置信息、输入信息或者系统运行环境,造成不能安全和有效地测试假设。
将问题过早地归结为极为不可能的因素(例如认为是宇宙射线造成数据变化,虽然有可能发生,但是并不应该在解决问题初期做这个假设),或者念念不忘之前曾经发生过的系统问题,认为一旦发生过一次,就有可能再次发生。
试图解决与当前系统问题相关的一些问题,却没有认识到这些其实只是巧合,或者这些问题其实是由于当前系统的问题造成的。(比如发现数据库压力大的情况下,环境温度也有所上升,于是试图解决环境温度问题。)
相关性(corelation)不等于因果关系(causation)。一些同时出现的现象,例如集群中的网络丢包现象和硬盘损坏现象可能是由同一个原因造成的,比如说供电故障。但是网络丢包现象并不是造成硬盘损坏现象的原因,反之亦然。更糟的是,随着系统部暑规模的不断增加,复杂性也在不断增加,监控指标越来越多。不可避免的,纯属巧合,一些现象会和另外一些现象几乎同时发生。
故障报告
每个系统故障都起源于一份故障报告,可以由自动报警产生,或者仅仅是你的同事说“系统很慢”。有效的故障报告应该写清预期是什么,实际的结果是什么,以及如何重现。理想情况下,这些报告应该采用一致的格式,存储在一个可以搜索的系统中,例如Bug记录系统中。
定位和恢复
正确的做法应该是:尽最大可能让系统恢复服务。这可能需要一些应急措施,比如,将用户流量从问题集群导向其他还在正常工作的集群,或者将流量彻底抛弃以避免连锁过载问题,或者关闭系统的某些功能以降低负载。
合理判定一个问题的严重程度需要良好的工程师判断力,同时,也需要一定程度的冷静。
优先恢复服务,再考虑排查问题:在大型问题中,你的第一反应可能是立即开始故障排查过程,试图尽快找到问题根源。这是错误的!不要这样做。
当你收到一个错误报告时,接下来的步骤是弄明自如何处理它。问题的严重程度大不相同,有的问题只会影响特定用户在特定条件下的情况(可能还有临时解决方案),而有的问题代表了全球范围内某项服务的不可用。
日志检查
在日志中支持多级记录是很重要的,尤其是可以在线动态调整日志级别。这项功能可以让你在不重启进程的情况下详细检查某些或者全部操作,同时这项功能还允许当系统正常运行时,将系统日志级别还原。如果系统有配套的测试用例,那么调试起来就会很容易。甚至这套测试用例可以用于非生产环境,非生产环境通常可以执行更具有侵入性和危害性的操作。
问题分解
在一个多层系统中,整套系统需要多层组件共同协作完成。最好的办法通常是从系统的一端开始,逐个检查每一个组件,直到系统最底层。这样的策略非常适用于数据处理流水线。在大型系统中,逐个检查可能太慢了,可以采用对分法(bisection)将系统分为两部分,确认问题所在再重复进行。
“什么”“哪里”和“为什么”
在一个异常系统中,该系统经常还正在执行某种操作,只是这些操作不是你想让系统执行的操作。那么找出系统目前正在执行“什么”,然后通过询问该系统“为什么”正在做这些操作,以及系统的资源都被用在了“哪里”可以帮助你了解系统为什么出错。
关注最后一个修改
过算机系统有惯性存在:我们发现,一个正常工作的计算机系统会维持工作,直到某种外力因素出现,例如一个配置文件的修改,用户流量的改变等。检查最近对系统的修改可能对查找问题根源很有帮助。
有针对性地进行诊断
针对具体系统开发的诊断工具和诊断系统会更有用。Gogle SRE花费了很多时间开发这样的工具。很多工具只适用于某个特定系统,但是在不同的团队和系统之间应该寻找共同点,以减少重复劳动。
测试要点
一个理想的测试应该具有互斥性,通过执行这个测试,可以将一组假设推翻,同时确认另外一组假设。
先测试最可能的情况:按照可能发生的顺序执行测试,同时考虑该测试对系统的危险性。先测试网络连通性,再检查是否是最近的配置文件改变导致用户无法访问某机器可能更合理。
某项测试可能产生有误导性的结果。例如:防火墙规则可能只允许某些IP访问,所以在你的工作机上ping数据库可能会失败,而实际从应用服务器上ping数据库可能是成功的。
执行测试可能会带来副作用。举例说明:让一个进程使用更多CPU可能会让某些操作更快,也可能会导致数据竞争问题更容易发生(单线程与多线程运行)。同样的,在运行中开启详细日志可能会使延迟问题变得更槽,同时也让你的测试结果难以理解:是问题变得更加严重了,还是因为开启详细日志的原因?
基些测试无法得出准确的结论,只是建议性的。死锁和数据竞争问题可能是非常难以重现的,所以有的时候你并不能找到非常确切的证据。
负面效果的价值
负面结果不应该被忽略,或者被轻视。意识到自己的错误通常意义更大:一个明确的负面结果可以给某些最难的设计问题画上句号。
就算该负面结果无法被其他人直接利用,这项试验收集到的数据也可以帮助其他人选择新的试验,或者避免之前设计中的问题。
如果你对一项测试的结果感兴趣,那么很有可能其他人也感兴趣。当你公布结果的时候,其他人不需要再重新设计和运行一套类似试验。
应对任何没有提到失败的设计文档、性能评估文档以及短文保持怀疑,因为这篇文章奇能经过了过度筛选,也可能因为作者的方法不是那么严谨。
工程师的判断力很重要
虽然带着一个未能确认的Bug上线并不是理想情况,很多时候消除所有已知Bug是不可行的。有的时候,我们只能依靠良好的工程师判断力来尽力消除风险。
11.紧急事件响应
破坏性测试
Google经常主动进行灾难处理和应急响应演习。SRE故意破坏系统、模拟事故,然后针对失败模式进行预防以提高可靠性。大多数时候,这些模拟事故都能按照计划进行,目标测试系统和依赖系统基本都能正常工作。我们利用这些测试曾经发现过一些系统的弱点和潜在的依赖关系,制定了修改计划以解决这些问题。但是有时候,我们的假设和实际结果相差很远。
做的不好的地方
由于我们没有在测试环境中测试回滚机制,没有发现这些机制其实是无效的,导致了事故总时长被延长了。我们现在要求在大型测试中一定先测试回滚机制。
不管风险看起来有多小,也要经过严格完整的部署测试。
做得好的地方
应急事故处理流程在本章提到的第一个事故出现之后很快成熟了起来,这些工程师很快很好地执行了这些流程。在事故中,整个公司的沟通和协作是一流的,多亏了应急事故管理系统和平时的训练。所有相关的团队都参与进来,共同帮助解决问题。
为事故保留记录
没有什么比过去的事故记录是更好的学习资料了。历史就是学习其他人曾经犯的错误。在记录中,请一定要诚实,一定要事无巨细。尤其重要的是,提出关键的问题。时刻寻找如何能在战术及战略上避免这项事故的发生。公布和维护事后报告,确保全公司的每个人都能从中学到你所学到的知识。
在事故结束后,确保自己和其他人切实完成事故中总结的待办事项。这样能够避免未来再次发生以同样的因素触发的同样的事故。一旦开始仔细学习过去的事故,我们就能更好地避免未来的事故。
12.紧急事件处理
过于关注技术问题
我们倾向于按技术能力指标聘请像Mary这样的人。所以她在灾难过程中忙着不断改变系统,英勇地尝试去解决服务问题一点儿也不奇怪。由于她正在忙着执行技术操作,所以根本没有时间和精力去思考如何能够通过其他手段缓解当前服务的问题。
嵌套式职责分离
在事故处理中,让每个人清楚自己的职责是非常重要的。有点反直觉的是,明晰职责反而能够使每个人可以更独立自主地解决问题,因为他们不用怀疑和担心他们的同事都在干什么。
如果一个人目前要处理的事情太多了,该人需要向计划负责人申请更多的人力资源。他们应该将一部分任务交接给其他人,有的时候这些人应该负责在事故流程管理系统中创建更多的子事故(即用来通知公司其他相关部门等。)另外一种方式是,某个负责人可以将某个系统事件完全交给同事来处理,由该同事直接向负责人汇报情况。
事故总控
事故总控负责人掌握这次事故的概要信息。
事故处理团队
事务处理团队负责人在与事故总控负责人充分沟通的情况下,负责指挥团队具体执行合适的事务来解决问题。
发言人
该人是本次事故处理团队的公众发言人。
规划负责人
规划负责人负责为事务处理团队提供支持,负责处理一些持续性工作、例如填写Bug报告记录系统,给事务处理团队订晚餐,安排职责交接记录。
实时事故状态文档
事故总控负责人最重要的职责就是要维护一个实时事故文档。该文档可以以wiki的形式存在,但是最好能够被多人同时编辑。
什么时候对外宣布事故
先宣布事故发生,随后找到一个简单解决方案,然后宣布事故结束,要比在问题已经持续儿个小时之后才想起流程管理更好。应当针对事故设立一个明确的宣布条件。
如果下面任何一条满足条件,这次事故应该被及时宣布
是否需要引入第二个团队来帮助处理问题?
这次事故是否正在影响最终用户?
在集中分析一小时后,这个问题是否依然没有得到解决?
事故流程管理最佳实践(需要不断演练)
划分优先级:控制影响范围,恢复服务,同时为根源调查保存现场。
事前准备:事先和所有事故处理参与者一起准备一套流程。
信任:充分相信每个事故处理参与者,分配职责后让他们自主行动。
反思:在事故处理过程中注意自己的情绪和精神状态。如果发现自己开始惊慌失措或者感到压力难以承受,应该寻求更多的帮助。
考虑替代方案:周期性地重新审视目前的情况,重新评估目前的工作是否应该继续执行,还是需要执行其他更重要或者更紧急的事情。
练习:平时不断地使用这项流程,直到习惯成自然。
换位思考:上次你是事故总控负责人吗?下次可以接一个职责试试。鼓励每个团队成员熟悉流程中的其他角色。
13.事后总结:从失败中学习
必要性
如果没有一种方法从已发生的事故中学习经验,那么事故就可能循环反复地发生。如桌不能解决这个问题,那么随着系统规模和复杂度的增加,事故可能成倍增加,最终导致我们没有足够的资源处理事故,从而影响最终用户。因此,事后总结是SRE的一个必要工具。
目的
书写事后总结的主要目的是为了保证该事故被记录下来,理清所有的根源性问题,同时最关键的是,确保实施有效的措施使得未来重现的几率和影响得到降低,甚至避免重现。
Google的事后总结哲学
基本的事后总结条件
用户可见的宕机时间或者服务质量降级程度达到一定标准。
任何类型的数据丢失。
on-call工程师需要人工介入的事故(包括回滚、切换用户流量等)。
问题解决耗时超过一定限制。
监控问题(预示着问题是由人工发现的,而非报警系统)。
对事不对人
不能把事后总结当成例行公事
最佳实践:避免指责,提供建设性意见
协作、共享、评审
关键的灾难数据是否已经被收集并保存起来了?
本次事故的影响评估是否完整?
造成事故的根源问题是否足够深入?
文档中记录的任务优先级是否合理,能否及时解决了根源问题?
这次事故处理的过程是否共享给了所有相关部门?
最佳实践:所有的事后总结都需要评审
未经评审的事后总结还不如不写。为了保障每个写完的草稿都得到评审,我们鼓励定期举行评审会议。在这些会议上,我们应该注意着重解决目前文档中的疑问和评论,收集相关的想法,将文档完成。
建立事后总结文化
为了更好地建立事后总结文化,SRE经常搞一些集体学习活动
本月最佳事后总结
Google+事后总结小组
事后总结阅读俱乐部
在引入事后总结机制的时候,最大的阻力来源于对投入产出比的质疑。下面的策略可以帮助面对这些挑战:
逐渐引入重后总结流程。
确保对有效的书面总结提供奖励和庆祝。
鼓励公司高级管理层认可和参与其中。
14.跟踪故障
警报聚合
多个报警可以被合并成一个。这些报警通知可能是由同一个故障造成的,也可以由非相关的事件组成,或者没有价值的记录性信息,或者只是暂时的监控失效报警。
试图减少同一个故障造成的报警信息总数量是值得做的,但是有时候在考虑过滤掉虚假报警以及漏报报警的危险性时,可能无法完全避免。
服务问题的数量本身,也不能说明修复某项服务的难度到底有多大,或者本次故障的影响有多大。
加标签
标签机制对团队来说非常有用,可以在不做详细分析的情况下快速看到服务的一些问题
分析
SRE当然不仅仅是响应和处理故障。历史数据对响应某个故障来说也很有用。我们可以通过查找“上次我们做了什么”作为起点处理本次故障。但是历史数据对分析系统性的、周期性的,以及更广范围内的系统问题也很有帮助。故障跟踪工具最重要的功能之一就是使用户可以进行这类分析。
底层的分析包括计数和基本的汇总统计报告。报告细节每个团队不同,但是一般包括每周/每月/每季度的故障数量和每次故障的报警数量。
数据分析的下一步是找到影响更广泛的问题,不仅仅是简单的计数,而是需要一些语义分析
额外的好处
让故障信息跨团队可见,可能在问题处理过程中提供巨大帮助,至少不会帮倒忙。
“造成了很多服务问题”可能是提高服务质量和降低报警数量的起始点。
15.数据完整性:读写一致
强需求
数据完整性意味着用户可以维持对云服务的访问,用户对数据的访问能力是最重要的,所以这种访问能力的完整性非常重要。
保障超高数据完整性的手段是主动探测和快速修复能力。
提供超高数据完整性的策略
在线时间
经常也用“可用率(availability)”指代,代表着某个服务可以被用户使用的时间比率。
延迟
服务对用户的响应时间。
规模
某个服务的用户数量,以及能够维持正常服务水平的最高负载。
创新速度
某个服务能够在合理成本下,为用户提供更好的服务的创新速度。
隐私
用户删掉服务中的数据后,数据必须在合理时间内被真正推毁。
备份与存档
存档的目的是将数据长时间安全保存,以满足审核、取证和合规要求。在这些情况下的数据恢复通常不需要满足服务的在线率要求。例如,我们可能需要将财务交易数据保存七年时间。为了达到这个目标,我们可以每个月将累积的审核日志迁移到离线的、异地的长期存档存储系统上。读取和恢复这样的信息可能需要一周时间,在长达一个月的财务审核过程中,这是可以接受的。
相对存档,当灾难来临的时候,数据必须从真实的备份中快速恢复,最好能维持服务在线率的要求。否则的话,受影响的用户将由于数据问题无法使用应用程序,直到数据恢复过程完成。
数据完整性是手段,数据可用性是目标
从用户的角度来看,仅仅保障数据完整性,而没有保障数据的可用性是没有意义的。完整性的数据需要确保访问的时效。
交付一个恢复系统,而非备份系统
我们不会强迫团队进行“备份”,而是要求:
各团队需要为不同的失败场景定义一系列数据可用性SLO。
各团队需要定期进行演练,以确保他们有能力满足这些SLO。
Google SRE保障数据完整性的手段
第一层:软删除
软删除机制可以大幅度减少支持人员的压力。软删除意味着被删除的数据立刻被标记为已删除,这样除了管理后台代码之外其他代码不可见。管理后台这里可能包括了司法取证场景、账号恢复、企业管理后台、用户支持,以及在线排错等。在用户清除自己的应用中的垃圾箱时应该采用软删除,同时提供某种支持工具允许有授权的管理员恢复误副除的文件。Google在使用量最高的工具上都实现了这种机制,否则用户支持所带来的压力是无法持续的。
软删除还意味着一旦数据被标记为已删除,在某段时间以后会真的被删除。这个时间的长度,尤其是在有很多短期数据的情况下,取决于某个组织的政策和相关的法律条文、可用的存储空间和存储成本,以及产品的价格和市场定位等。常见的软删除时间是15、30、45或者60天。在Google的经验中,大部分账号劫持和数据完整性问题都会在60天内汇报或者检测到。因此,为软删除保存超过60天的需求可能没有那么强烈。
有时候可能会再增加一层软删除机制,我们称之为“懒删除”机制。可以将“懒删除”认为是某种幕后清理机制,由存储系统控制(与此相比,软删除是由程序或者服务直接控制的)。在懒删除场景下,由某个云计算应用程序删除的数据马上对应用程序不可用,但是由云计算服务提供商保留几周时间再彻底销毁。懒删除不一定在所有的策略中都适用:在一个短期数据很多的系统中保存长期懒删除数据可能成本会很高,甚至在某些需要保障已删除数据的销毁时间的系统中不可行(例如某些隐私敏感的程序)。
第二层:备份和相关的恢复方法
在设计备份还原系统时,必须考虑:
使用哪种备份和还原方法。
通过全量或者增量备份建立恢复点(restore point)的频率。
备份的存储位置。
备份的保留时间。
“快照”在这里指的是对存储实例的一个只读、静态的视图,如SOL数据库的一个快照。快照通常使用Copy-on-write”技术实现,以提高存储效率。快照成本来自两个方面:第一,它们与在强数据存储挤占存储容量。第二,数据修改速度越快,copyon-write的作用越有限。
第一级备份是那些备份频率很高,并且可以快速恢复的备份。这些备份保存在与线上数据存储距离最近的地方,使用与数据存储相同或者是非常相似的存储技术。
第二级备份的频率较低,只保留一位数或者两位数字的天数。第二级备份保存在当前部署点的随机读写分布式文件系统上。这些备份可能需要数个小时来备份,是用来为服务所使用的数据存储出现的相关问题提供额外保护的,但是要注意,这无法为用来保存备份的技术栈自身的问题提供保护。
冷存储,包括固定的磁带库以及异地备份存储设施(不管是磁带,还是磁盘)。这些级别的备份可以保护单个部署点级别的故障,例如数据中心电源故障,或者是Bug造成的分布式文件系统的数据损坏。
1T vs.1E:存储更多数据没那么简单
问题
我们用同样的策略来校验700 Petalbyes的结构化数据。就算我们使用一个理想化的SATA2.0接口(300MB/s的性能),仅仅是遍历一遍所有数据进行最基本的校验也将需要80年。
思路
正确平衡数据分片。
保证每个分片之间的独立性。
避免相邻并行任务之间的资源抢占。
第三层:早期预警
越早检测到数据丢失,数据的恢复就越容易,也越完整。
带外数据校验流水线
安排一些开发者来开发一套数据校验流水线可能会在短期内降低业务功能开发的速度。然而,在数据校验方面投入的工程资源可以在更长时间内保障其他业务开发可以进行得更快。因为工程师们可以放心数据损坏的Bug没那么容易流入生产环境
尺度
一个有效的带外数据校验系统需要下列元素:
校验任务的管理。
监控、报警和监控台页面。
限速功能。
调试排错工具。
生产应急应对手册。
校验器容易使用的数据校验API。
大部分高速进行的小型开发团队都负担不起设计、构建和维护这样的系统所需的资源。
最好的办法是单独组织一个中央基础设施组为多个产品和工作组提供一套数据校验框架。该基础设施组负责维护带外数据校验框架,而产品开发组负责维护对应的业务逻辑,以便和他们不断发展的产品保持一致。
确保数据恢复策略可以正常工作
主动检测这些问题需要以下步骤:
持续针对数据恢复流程进行测试,把该测试作为正常运维操作的一部分。
当数据恢复流程无法完成时,自动发送警报。
SRE的基本理念在数据完整性上的应用
1)保持初学者的心态
2)信任但要验证
3)不要一厢情愿
4)纵深防御
16.迅速培养SRE加入on-call
新的SRE已经招聘到了,接下来怎么办
现有的on-call工程师如何能够评估新手是否已经准备好参加on-call?
我们如何能够更好地利用新员工带来的激情与好奇心,使老员工也能从中获利?
组织哪些活动不仅可以丰富团队知识,还能够获得大家的喜爱?
我们如何能够更好地利用新员工带来的激情与好奇心,使老员工也能从中获利?
组织哪些活动不仅可以丰富团队知识,还能够获得大家的喜爱?
培训初期:重体系,而非混乱
被动式教育的弊端:关注于运维,被动性的SRE团队一般采用这种被动式的教育方式来“培训”新员工。如果幸运的话,新招来的、习惯在未知中探索的工程师最后能够从这种大坑里爬出来。但是更常见的是,很多很有能力的工程师都没法在这种环境中成长。虽然这种培训最终可能能够培养出一些不错的运维工程师,但实际效果肯定也不会太好。这种培训方式同时假设该团队的大部分知识都可以靠“动手实践”来获得,而不是靠逻辑推理得出。如果这个职位只需要处理工单就修了,那么这个职位其实并不是一个SRE职位。
系统性、累积型的学习方式
系统中加入某种顺序性,以便新的SRE成员可以建立某种学习路径。任何类型的系统性培训都要比直接处理随机出现的工单和琐事要好,但是我们应该有选择地将一些理论性和实践性的学习组合到一起:一些新成员经常会用到的、系统的抽象概念应该优先,而学员也应该尽早进行真实的实践操作。
考虑在服务访问权限控制配置中实现一种分层模式。第一层访问权限允许学员只读访问组件的内部信息。接下来则允许修改生产环境状态。随着检查列表项目的完成,学员将会逐步拥有系统的更高权限。搜索SRE团队将这称为“升级”,准“所有的学员最后都会被赋予系统最高权限。
目标性强的项目工作,而非琐事
所有的工程师都会被分配一个初始项目,给他们提供足够的基础设施知识,同时让他们可以为服务做一点小的但是有意义的贡献。让新的SRE成员将时间同时分配在学习和项目工作中可以给他们一种参与感和效率感,这比让他们专攻两者中的任意一个要好。
常见的新手项目类似于:
在服务技术栈中增加一个小的,但是用户可见的功能修改,接下来跟随这个修改一直到发布到生产环境中。了解开发环境的配置和二进制文件的发布流程可以确保他们和开发团队联系密切。
针对现有的服务监控盲点增加新的监控。新手需要了解监控逻辑,同时将这些异常情况与系统知识相结合。
选择一个还没有被自动化的痛点进行自动化,使得新的SRE可以给团队成员减轻一些日常负担,从而受到团队的欣赏。
培养反向工程能力和随机应变能力
SRE同时也应该具有如下特点:
在日常工作中,他们会遇到从未见过的系统,必须要具有很强的反向工程能力。
在海量规模下,很多异常情况都很难检测,他们必须具有统计学知识,用统计学而不是流程化的方式去发现问题。
当标准的流程不工作时,他们必须能够随机应变,解决问题。
通过对系统工作原理的基本理解,同时愿意深入研究调试工具、RPC框架,以及系统的二进制文件来理解其中的数据流动,SRE就能够在陌生环境中更高效地处理始料未及的额外难题。教授SRE成员如何调试和诊断应用程序,同时让他们练习利用这些调试信息进行推断,可以使他们在日后的工作中更习惯使用这种方式工作。
统计学和比较性思维:在压力下坚持科学方法
将SRE处理大规模系统紧急情况的方式理解为他们在实时展开的决策树中不断抉择的过程。
因为时间通常是有限的,SRE必须能够有效地在决策树中进行抉择。这种能力的获得通常要靠经验积累,而经验只能通过有效和真实的实践获得。
随机应变的能力:当意料之外的事情发生时怎么办
在故障发生时固守陈规而不去做现场分析,可能会导致无法找到问题根源。在非常复杂的故障排除过程中,SRE通常需要利用很多未经验证的假设来进行决策。在SRE培训初期加入一些关于决策“陷阱”的描述,以及关于如何能够及时抽身,从更高的层面换一个角度去思考问题的解决方案,是非常有价值的。
将知识串联起来:反向工程某个生产环境服务
自行构建出整个技术栈的组件图,同时与资深SRE共同讨论。
对事故的渴望:事后总结的阅读和书写
Google的某些SRE团队会举办“事后总结团体学习”,将一些有价值的事后总结文档集中分发、阅读,并组织集体讨论。原始作者经常会被请到这些会议中,其他团队则会举办“故障沙龙”这样的活动,请原始作者以非正式的形式出席,描述故障的过程,并且组织讨论。
故障处理分角色演习
如何将SRE文化——不断解决问题的文化—传授给新员工,同时保证老员工始终能跟上不断变化的环境和服务发展也是一个挑战。GoogleSRE团队通过一个老传统—“故障处理分角色演习”来解决这些问题。这个活动同时也被称为“命运之轮”(whel of misfortune)或者“走木板”(walk the plank)等,这些名字对新加入的SRE来说不会那么吓人。
维护文档是学徒任务的一部分
很多SRE团队要维护一个“on-cal学习检查列表”。该列表中包含一系列阅读材料,以及关于系统的各种技术和知识的完整列表,学员必须充分掌握该列表才能进行见习on-call。
尽早、尽快见习on-call
学员可以和主on-call共享一个终端,或者仅仅是坐在一起讨论。在故障解决后的某个合适时机,on-call可以和学员一起讨论背后的处理逻辑和过程
当一个报警发生时,新手SRE并不是问题解决的负责人,这样可以让他们在没有任何压力的情况下进行操作。他们现在可以亲眼观察故障发展,而不是在事后学习
如果某个较大的故障发生,书写事后总结比较必要时,on-ca成员应该将学员加为共同作者。不要将整个书写过程全部交给学员,因为这可能会导致他误认为事后总结是一项项事,专门交给新手来完成的:千万不要造成这种到象。
17.处理中断性任务
紧急警报
是关于生产环境中出现的问题以及相关问题发出的警报,目的在于通知接收人处理紧急情况。有的时候,这些问题是单调重复的,处理起来不需要很多思考。但是,有的时候问题需要详细地在线调查才能解决。紧急警报通常配有预期的响应时间(SLO),一般是几分钟。
工单
是指那些需要进行某种操作以应对客户的需求。和紧急警报类似,工单也可以是很简单的、重复的,几乎不需要临场发挥。简单的工单可能只是需要对某个配置文件进行代码评审。复杂的工单则可能需要处理一个较为复杂,不那么寻常的设计评审,或者容量规划方案评审。工单同样也有SLO,但是它的响应时间一般是数小时,甚至数天数月。
工单处理应该由全职人员负责,同时保证占用合理的时间。如果团队目前的工单主on-call 和副 on-call都处理不完,那么需要重新架构整个工单的处理流程,保障任何时间都有两个全职员工处理工单。不要将复杂分散到整个团队中去。人不是机器,这样做只会干扰员工,降低他们的工作效率。
工单的处理也应该有个交接过程,和on-call一样。交接过程可以保证每个处理人之间共享状态。
日常运维任务
包括团队负责的代码或者配置文件发布,或者是处理临时的但是又紧急的客户需求。虽然这些任务没有指定的SLO,但是这些任务会打断日常的工作。
如何决策对中断性任务的处理策略
SRE团队发现下列指标对制定策略很有帮助:
中断任务的SLO,即预期的响应时间
排队的中断性任务有多少
中断性任务的严重程度
中断性任务的发生频率
可以处理某种中断性任务的人有多少(某些团队要求成员必须处理一定数量的工单才能加入on-call)
流状态
流状态(flow state)是一个软件工程行业内被普遍接受、人尽皆知的理念。“在状态里”可以提升生产力,也可以提升创造性,甚至艺术创造性。进入这个状态可以鼓励员工真正地掌握和优化某个他们负责的任务和项目。但是,如果有其他的事情打断他们,他们就会失去这个状态。我们的目标是尽可能让员工在这个状态下工作。
分心
他可以通过关闭E-mail、关掉IM,或者其他手段来减少一定的干扰。但是某些干扰是政策造成的,以及一些无法避免的责任造成的。
我们可以说某种程度的干扰是不可避免的,也是有意为之的。这是正确的:每个人都有甩不掉的Bug,同事之间也会有关系的产生与职责的分配。然而,作为团队来说,是有一些管理方式能使更多的员工不受干扰的。
极化时间
将工程师当成是可以随时中断、上下文切换没有成本是不正确的。给每次上下文切换加上成本的考虑。在项目工作中,一次20分钟的中断性任务需要进行两次上下文切换,而这种切换会造成数个小时的生产力的丧失。
极化时间意味着当每个人来上班时,他们应该清晰地知道自己今天是否只是做项目工作,还是只是做中断性工作。这意味着他们可以更长时间地专注于手上的工作,不会不停地被那些他们本不应该负责的事情所打扰。
并行
管理层不应该期望员工在on-call的同时还能在项目上有所进展(或者其他高上下文切换成本的活动)。
尊重自己,也尊重用户
一定要记住:
团队应该为自己的服务设置合理的服务水平。
将某些事务推回给客户解决是可以的。
在尊重用户和尊重自己之间寻找一个平衡点。我们的指导思想应该是确保用户发来的请求应该是有意义的、合理的,同时提供了所有需要准备的材料。同样,我们处理这样的请求也应该是非常及时而且有效的。
18.通过嵌入SRE的方式帮助团队从运维过载中恢复
外部视角
SRE应该关注于改善这个团队的行事方式,而不是简单地帮助团队清理积压的工单。通过观察团队的日常工作,提出改善性意见,该SRE可以帮助团队用全新的现角来审视自己的日常工作。这往往是团队本身的成员做不到的。
了解服务,了解上下文
日益增加的工单不应需要更多的SRE来处理。SRE模型的目标是仅仅在系统复杂度上升的时候才增加新人。你应该尝试引导团队建立健康的工作习惯,这样能够减少花费在工单上的时间。
Ops 模式与非线性扩展
在Ops模式下的团队通过增加更多的管理员来解决这个问题,SRE则恰恰相反。他们通过编写软件系统或者消除系统瓶颈的方法来解决这个问题。这样运维一个服务所需的人数不会与服务的负载同步增加。时刻记住,你的工作是保证服务正常运转,而不是避免警报发生。
确定最大的压力来源
SRE团队陷入Ops模式的原因是过分关注如何快速解决紧急事件而不是如何减少紧急事件的数量。
由于团队的历史和视角问题,一些非常小的问题可能其实正在给团队带来很大负担,而他们自己却不知道。
找到导火索
知识代沟
在大型团队中,团队成员可能会过度专业化。
其他团队成员缺乏只有他才了解的关键系统的知识。
SRE直接参与开发的功能变得越来越重要
这些服务通常没有得到和一般的新功能上线所需的同等水平的关注,因为在规模上他们更小并且当时至少有一位SRE支持。
对“未来的一件大事”的过度依赖
团队成员有时会忽略某种问题长达几个月的时间,因为他们相信“马上上线”的新解决方案能够解决该问题,临时措施没有意义。
开发团队和SRE都视而不见的警报
这样的警报经常被定性为暂时性的,但是这些警报仍然会让团队成员分心。要么仔细地将此类警报调查清楚,要么就修改警报规则让它们不再出现。
任何有客户投诉,并且缺乏一个正式的SLI/SLO/SLA的服务
任何一个容量规划都是“增加更多的服务器”的服务:“我们的服务器昨天晚上内存不足了。”容量规划必须具有足够的前瞻性。
事后总结中的待办事项仅仅只有“回滚导致服务故障的变更”的服务
现有的SRE以“我们什么也不知道,开发者才明白”来应对的关键组件
书写一个好的事后总结作为示范
不要尝试改正之前的错误,而是应该亲自负责下一次事后总结的书写。在你和团队的工作过程中,肯定会有至少一次事故发生。永久性地修复根源问题长期来看可以减少事故对团队成员的时间的影响。
将紧急事件按类型排序
不应该存在的紧急事件。这些紧急事件会导致那些一般被称作OpS工作和琐事
其他的紧急事件可能会让on-call成员感到压力巨大,又或者会使他愤怒地敲击键盘。这类紧急事件实际上是日常工作的一部分,团队需要通过构建对应的工具来控制压力
你应该将团队遇到的紧急事件分为琐事的和非琐重的。最后,将这个列表交给团队并且清晰地解释哪些紧急事件应该被自动化,而其他的紧急事件则是运维服务必须承担的工作。
解释你的逻辑推理过程
如果不够幸运,没有人会要求你做出解释。这时,你应该通过直接解释你的所有决定来绕过这个问题,不管是否有人要求你这样做。当做出解释时,记得要引用你的建议中的那些基础理念。这样做有助于建立团队的心理模型。如果你不解释逻辑推理过程,或者解释得不够充分,就可能会造成团队也形成这种懒惰的风气。所以一定要避免。
提出引导性问题
引导性问题的例子:
“我看到任务失败的警报经常发生,但是on-cal工程师通常什么都不做。这样会对SLO有什么影响?”
“这个上线过程看起来非常复杂。你知道为什么创建一个新的服务实例需要这么多的配置文件的更新吗?”
引导性问题的反例:
“这些旧的、停滞的发布是什么情况?”
“为什么某个组件要做这么多的真情?”
非紧急警报事件
非紧急警报事件:
①一个应该有紧急警报发生却没有的问题。
②非紧急警报事件,但是却需要引起注意的。如影响范围较小的数据损坏问题,或者是非直面用户的系统部分的速度缓慢问题。
③非紧急警报事件,但是不需要引起注意的。这些警报应该被去掉,因为它们制造了额外的噪声,在值得注意的问题之外分散了工程师的注意力。
19.SRE与其他团队的沟通与协作
沟通:生产会议
生产会议通常每周进行一次;鉴于SRE对于毫无意义的会议十分反感,这个频率似乎是合适的:有足够时间积累足够的素材使得会议有价值,同时又不会太频繁而总让人们找借口不参加。每次会议通常持续30到60分钟。如果会议过短,意味着某些东西没有充分讨论,或者意味着是服务内容太少。如果会议过长则意味着你可能陷入了细节讨论之中,又或者是待讨论的东西太多,应该按服务或者团队进一步拆分会议。
轮值会议:确实不是每个人都有同等水平的主持技巧,但是由于轮值带来的集体参与感的价值很高,我们可以接受一些临时的次优性选择。更重要的是,这是提高个人主持能力的好机会。
平衡势力:在两个SRE团队视频会议时,如果一个团队比另外一个大很多,我们建议从较小的团队一边选择主席。更大的一方会自然而然地安静下来,一些不平衡的团队规模所造成的不良影响(这些会由于视频会议的延迟而变得更槽)将得到改善。
出席人员
不那么活跃的服务可能只需要产品研发团队的一个代表出席,或者仅仅是获得产品研发团队的一个承诺就够了:承诺他们会阅读和评论会议日程。
如果研发团队非常大,选择一部分人作为代表。
那些忙碌却重要的与会者可以通过事先提供个人反馈和引导的方式参加,或者使用事先填写的议程方式参加
多人协作:让这个会议更高效和更具包容性的一个独特地方是使用Google Docs的实时协作功能
用“草根”想法、评论和其他信息事先填充议程
非常有效地进行会前多人并行议程准备。
专业化的优缺点
专业化有很多优势,因为它能够大幅提高技术熟练度。但同时专业化也是有弊端的,因为它会导致局部化,忽视大局。
高效工作的技术
单人项目最终肯定会失败,除非此人个人能力超强或者待解决的问题是非常简单直接的。做成任何高价值的事情都需要很多人共同协作。正因为这样,SRE团队需要良好的协作能力。
本地团队靠沟通,外地团队靠书面或旅行:在做本地团队边界之外的工作时要想成功就一定需要良好的沟通技巧。而与异地团队合作,或者与跨越时区的团队一起工作则需要极好的书面沟通能力或者是大量的旅行,这样才能建立人与人之间的高质量关系。
面谈的重要性:书面沟通能力再强,随着时间的推移,人们对你的印象也会逐渐淡薄成一个电子邮件地址,直到你再次出现进行直接沟通。
产品开发组织和SRE之间的合作最好发生在设计阶段的早期,最理想的状态是在任何一行代码还没有被提交之前。SRE最适合为架构和软件的行为提供建议,后期进行这些改造是相当困难的(如果可能的话)。
20.SRE参与模式的演进历程
PRR模型
SRE参与一个项目时,最典型的第一步是进行生产就绪程度评审(PRR)。该流程根据服务的具体细节来找出在可靠性方面的欠缺之处。通过PRR流程,SRE寻求运用他们所学到的经验来确保服务生产运行中的可靠性。只有通过PRR评审,SRE团队才会同意承担该服务的运维责任。
替代性支持
不是所有的Google服务都有SRE的紧密参与。有以下几个原因:
·许多服务不需要高可靠性和高可用性,可以通过其他方式支持该服务。
开发团队的数量总是会超过SRE团队的可支持的数量。
·许多服务不需要高可靠性和高可用性,可以通过其他方式支持该服务。
开发团队的数量总是会超过SRE团队的可支持的数量。
PRR评审的目标
验证该服务符合公认的标准的生产部署方式和运维方式,同时该服务负责人已经准备好与SRE一起工作,利用SRE的知识改进服务。
提升服务生产环境中的可靠性,并最小化可预见的故障的数量和严重程度。PRR会关注SRE所关注的生产环境的所有方面。
确定最适合的SRE:
为该服务建立一个SLO/SLA
为可能的、为了提高可靠性的破坏性设计变更制定计划。
制定交接计划和培训计划。
该流程的目标是对PPR流程、最终目标,以及结果形成一个共识。
0 条评论
下一页