数据API 数据治理 会员 案例 开发者
掌握聚合最新动态了解行业最新趋势
API接口,开发服务,免费咨询服务
新闻动态 > 媒体报道

一个Google SRE工程师眼中的8点运维原则

我是 Google 一名 SRE (运维)工程师,在过去系列文章中对『SRE: Google 运维解密』一书提出了自己的见解。本文所有见解皆为个人观点,不代表 Google 公司立场。

我们来看书中第一章的一些观点: Google 对运维的解决之道:网站可靠性工程(Site Reliability Engineering)[1]。

虽然每个 SRE 团队都有自己的工作流程、优先级定义以及日常工作规范,但是所有的 SRE 团队都有一套共同的核心方法论。一般来说,SRE 团队要承担以下几类职责:可用性改进,延迟优化,性能优化,效率优化,变更管理,监控,紧急事务处理以及容量规划与管理。SRE 管理层针对这些内容制定了一套完整的沟通准则和行事规范,这些规范规定了 SRE 是如何操作 Google 生产环境的,也规定了 SRE 如何和产品研发部门、测试部门、最终用户进行有效沟通。这些准则和规范能够帮助每一个 SRE 部门保持一个良好的研发、运维工作的平衡。


因此,关键的点是:

SRE 团队要承担以下几类职责:可用性改进,延迟优化,性能优化,效率优化,变更管理,监控,紧急事务处理以及容量规划与管理


线上项目是错综复杂的,如果你只是部署某人的代码,你如何对其服务的响应延迟负责?还好,你有一些标准化的手段,比如使用容量规划、监控并配合变更管理来帮助你。

通常,运维的工作是对系统变慢或不可用的情况负责,从长期来说,需要与开发团队沟通,将潜在的问题修复;从短期来看,有时候运维增加更多的服务器也许反而降低了性能?或者想让程序运行更快反而会降低了可靠性。

下面针对 Google SRE 的 8 大核心原则做一些个人解读。

1、确保长期关注研发工作

如前所述,Google 将 SRE 团队的运维工作限制在 50% 以下。SRE 团队应该将剩余时间花在研发项目上。在实践中,SRE 管理人员应该经常度量团队成员的时间配比,如果有必要的话,采取一些暂时性措施将过多的运维压力转移回开发团队处理。例如说:将生产环境中发现的 Bug 和产生的工单转给研发管理人员去分配,将开发团队成员加入到轮值 on-call 体系中共同承担轮值压力等。这些暂时性措施应该一直持续到运维团队的运维工作压力降低到 50% 以下。在实践中,这种措施实际形成了一个良性循环,激励研发团队设计、构建出不需要人工干预、可以自主运行的系统。只有整个产品部门都认同这个模式,认同 50% 的安全线存在的重要性,才会共同努力避免这种情况的发生。

我在上一篇文章中提到了:我们有管理手段支持回传需求给开发人员,这一做法是 SRE 拥有的一个巨大杠杆。

这里提到的 50% 上限,实际上我在 Google 的任何小组中都没有去精确测量。 在实践中,当有一个团队需要做太多的线上操作工作时,我们会测量具体的工作,例如故障问题数量和提交工单数量。

 下文介绍了这一块是如何工作的。

SRE 处理运维工作的时候的一项准则是:在 8 ~ 12 小时的 on-call 轮值期间最多应该只处理 2 个紧急事件。这个准则保证了 on-call 工程师有足够的时间跟进紧急事件,正确地处理并且恢复服务,并且要撰写一份事后报告。如果一次轮值过程中处理的问题过多,那么每个问题就不可能被详细调查清楚,运维工程师甚至没有时间从中学到任何知识。如果一个小项目无法做到合理报警,规模扩大之后这个情况就会更严重。相对而言,如果一个项目的紧急警报非常少,持续性稳定运行,那么保持这么多 on-call 工程师可能就是在浪费时间。

在 Google,SRE 没有 8 小时的轮班。 我们使用 12/12 轮班或 24 小时轮班。 无论是对 12 小时还是 24 小时班次来说,每个班次“2 次事件”的指标依然适用。 这确保了 24 小时轮班的工程师也有足够的时间来处理他们的事件管理和后续跟进工作。

我不喜欢把这个指标作为平均值。每个班次记录的平均事件数不是我在这里跟踪的:如果每个班次记录的平均数是 0.4,但每月有 4 - 5 天的 3+ 事件,我会认为这是一个不健康的负载,并尝试解决它。 

正常状况是是让每一天需要 SRE 响应的紧急事件都是一个合理的负载,每一个事件都可以被专业地处理。你必须优先处理某一种问题的情况不会发生。

所有的产品事故都应该有对应的事后故障总结,无论有没有触发警报。这里要注意的是,如果一个产品事故没有触发警报,那么事后总结的意义可能更大:因为它将揭示监控系统中的漏洞。

事后故障总结应该包括以下内容:故障发生、发现、解决的全过程,故障的根本原因,预防或者优化的解决方案。

Google 的一项对内准则是“对事不对人”,事后总结的目标是尽早发现和堵住漏洞,而不是通过流程去绕过和掩盖它们。在 SRE 第15章中详细讨论了事后分析。

本周一位同事曾对我说:“今天的故障发生后,我和开发者一起开始了事后总结,他们添加了一段话来解释他们这次变更如何破坏了生产环境,我不得不跟他们聊聊怎么去掉这个描述。

这是因为:如果你专注于找到某人或某事来解释一个故障,那么你就会把自己限制在一个原因里面。在一个故障总结中,你应该列出所有导致故障触发的因素,而不是把它当作一个承认错误的地方。

2、在保障服务 SLO (Service Level Objective) 的前提下最大化迭代速度

产品研发部门和 SRE 之间可以通过消除组织架构冲突来构建良好的合作关系。在企业中,最主要的矛盾就是迭代创新的速度与产品稳定程度之间的矛盾。正如上文所说,其表现形式可能是间接的。在 SRE 模型中,我们选择正面面对这种矛盾,使用的工具是错误预算

我的预算:21分钟

“错误预算”起源于这样一个理念:任何产品都不是也不应该做到 100% 可靠。(显然这个并不适用于心脏起搏器和防抱死刹车系统等)。一般来说,任何软件系统都不应该一味地追求 100% 可靠,因为对最终用户来说,99.999% 和 100% 的可用性是没有实质区别的(99.999% 的可用性是每天 0.6s,每月 26s,每年 5m 的不可用)。从最终用户到服务器之间,有很多中间系统(用户的笔记本电脑、家庭 WiFi、网络提供商和输电线路等)这些系统综合起来可靠性要远低于 99.999%。所以,在 99.999% 和 100% 可靠之间的区别基本上成为其他系统的噪声。就算我们花费巨大精力将系统变为 100% 可靠,也并不能给用户带来任何实质意义上的帮助。

在我在广告 SRE 时,SRE会查看 Google 的广告收入(基于公开发布的收入数据,而不是任何机密信息),并计算每年额外的“9”可用性的价值。这表明有时你确实关心 0.001% 的可用性提升!

如果 100% 不是一个正确的可靠性指标,那么多少才是呢?这其实并不是一个技术问题,而是一个产品问题。要回答这个问题,必须要考虑以下几个方面 :

  • 基于用户的使用习惯,服务可靠性要达到什么程度用户才会满意?

  • 如果这项服务可靠程度不够,用户是否有其他的替代选择?

  • 服务可靠程度是否会影响到用户对这项服务的使用模式?


测试当产品稍微不可靠时,用户的使用会发生什么是很容易做到的:if(user-> in_experiment_set()&& random()< 0.0005),但这不是那种容易让你的经理批准的测试。

公司的商业部门或者是产品部门必须建立起一个合理的可靠性目标。一旦建立,“错误预算”就是“1 - 可靠性目标”。如果一个服务的可靠性目标是 99.99%,那么错误预算就是 0.01%。这意味着产品研发部门和 SRE 部门可以在这个范围内将这个预算用于新功能上线或者产品的创新等任何事情。

尽量不要把错误预算都花在一个地方。

“错误预算”都可以用于什么范畴呢?研发团队需要用这个预算上线新功能,吸引新用户。理想情况下,我们应该使用这个错误预算来最大化新功能上线的速度,同时保障服务质量。这个基本模型建立起来之后,许多常见的战术策略,例如灰度发布,1% A/B 测试等就全说得通了。这些战术策略都是为了更好地使用整个服务的错误预算。

这里介绍了灰度发布的想法:如果推出一个功能,假设它是 20% 不可靠,但只有 5% 的用户可以访问,结果也只有 1% 的中断。 

灰度发布意味着您可以快速发布那些可能存在风险的软件,但也是需要控制在你的全部错误预算内。

通过引进“错误预算”的概念,我们解决了研发团队和 SRE 团队之间的组织架构冲突。SRE 团队的目标不再是“零事故运行”,SRE 团队和产品研发团队目标一致,都是在保障业务服务可靠性需求的同时尽可能地加快功能上线速度。这个改动虽小,意义却很大。一次“生产事故”不再是一件坏事,而是一个创新流程中不可避免的环节,两个团队通过协作共同管理它。

我已经跟开发人员谈过了:“你太小心了,停止多次检查所有细节,那样会导致上线太慢。

3、监控

监控系统是 SRE 团队监控服务质量和可用性的一个主要手段。所以监控系统的设计和策略值得着重讨论。最普遍和传统的报警策略是针对某个特定的情况或者监控值,一旦出现情况或者监控值超过阈值就触发 E-mail 报警。但是这样的报警并不是非常有效:一个需要人工阅读邮件和分析报警来决定目前是否需要采取某种行动的系统从本质上是错误的。监控系统不应该依赖人来分析信息进行报警,而是应该由系统自动分析,仅仅当需要用户执行某种操作时,才需要通知用户。

在 Google 有一个规则:没有不需要采取行动的警报。如果您遇到一个自己认为不需要执行操作的警报,您需要采用自动化的手段来修复该警报。

以下是各种我认为值得推荐的做法:

  • 明确修复的责任,并跟进相关团队。

  • 提交 bug 并跟踪记录为什么会这样的问题。

  • 教育某人用更好的方式来完成,避免出现报警的情况。

  • 更新已有的 bug,输出更多调试信息。

  • 调整警报阈值,避免用户并没有出现访问问题时候发送报警。

  • 删除那些无效警报,因为它是无用的和不相关的。

监控不做任何事情是不可能的,有三种有效的监控输出:

警报

意味着收到警报的用户需要立即执行某种操作,目标是解决某种已经发生的问题,或者是避免即将要发生的问题。

这使我所拥有的每个设备都会产生大量的噪音。如果我在 5 分钟内没有回应,它会找到我的替代者,他的工作是采取行动。

我所在的 SRE 团队有一个送花规则,如果问题落到替代者来处理,这对主负责人来说是个悲剧,你将需要给替代者送去花和一张卡。

工单

意味着接受工单的用户应该执行某种操作,但是并非立即执行。系统并不能自动解决目前的情况,但是如果一个用户在几天内执行这项操作,系统不会受到任何影响。


当我 oncall 轮值时,我能每天检查四次工单队列就很不错了。他们重要但不紧急,而且通常也是超级耗时的问题,因为他们需要大量的分析来解释发生的原因。 “为什么我们今天比一周前增加了 25% 的磁盘 I/O,并且达到了吞吐量限制?”


日志

平时没有人需要关注日志信息,但是日志信息依然被收集起来以备调试和事后分析时使用。正确的做法是平时没有人主动阅读日志,除非处理其他请求的时候被要求这么做。

我要指出,下次有人如果试图实现更多的“严重:电子邮件”警报,所有收到的都将是无用的噪音。


4、紧急事件处理

可靠性是 MTTF(平均失败时间)和 MTTR(平均恢复时间)的结合结果。评价一个团队将系统恢复到正常情况的最有效指标,就是 MTTR

任何需要人工操作的事情,都只会延长恢复时间。相比之下,一个可以自动化恢复的系统即使有更多的故障发生,也要比事事都需要人工干预的系统可用性更高。当人工介入不可避免的时候,我们也发现与“车到山前必有路”的态度相比,通过事先预案并且将最佳方法记录在“运维手册”上通常会使 MTTR 降低 3 倍以上。初期几个万能的工程师的确可以解决生产问题,但是长久看来一个手持“运维宝典”经过多次训练的 on-call 工程师才是正确之路。虽然不论多么完备的“运维手册”也无法替代人的创新思维,但是在巨大的时间压力和产品压力下,运维手册中记录的清晰调试步骤和分析方法对处理问题的人是不可或缺的。因此,Google SRE 将大部分重心放在“运维手册”的维护上,同时通过“Wheel of Misfortune”等项目培训团队成员。

通过事先预案并且将最佳方法记录在“运维手册”上通常会使 MTTR 降低 3 倍以上!

运维手册的质量差别也是千差万别。从“这样过时的字在这里没有什么意义的”,到“这本手册将需要我 45 分钟阅读,并且重要的信息被埋在一个段落的末尾附近的链接”到“这本手册告诉我如何诊断和解决第一句中的问题“。

不同团队对运维手册有很多不同的看法。一种看法是你应该非常熟悉你所有的操作,因此你不需要手册,你需要的是一个精确的监视控制台,以便你知道采取什么行动。

没有手册是一个奢侈的事情,只有在团队需要支持的事情很少的情况下可行。我们这些支持很多系统的人不能将所有内容全部放入脑子。

相比之下,我个人的意见是,如果手册无用,也不是警报,就应该重建它,或删除警报和手册。因为没有足够有用的背景信息的警报是如此危险。

5、变更管理

SRE 经验告诉我们,大概 70% 的生产事故由某种部署的变更而触发。变更管理的最佳实践可使用自动化来完成以下几个项目:

  • 采用渐进式发布机制。

  • 迅速而准确地检测到问题的发生。

  • 当出现问题时,安全迅速地回退改动。

    这三点可以有效地降低变更给 SRE 和最终用户带来的时间成本和服务质量的下降。通过将人工因素排除在流程之外,这些操作将不再受到经常发生在人身上的“狼来了”思想以及对大量重复性劳动的关注疲劳所影响。于是,变更执行的速度和安全性同时得到了提高。

这部分内容较少,我相信其他章节会谈到这一点,但我要在这里做出强调:70% 的生产事故由某种部署的变更而触发。70% 的故障可以通过不做任何事情来避免!我们是自己的敌人。

因此,可以将错误预算支出降低高达 70% 的基本工具是:及时发现上线出现问题并快速回滚。这是一个多么简单的事情!你需要多长时间才能注意到这是一个有问题的版本发布?回滚它需要多长时间?在回滚完成之前,它影响了多少人?

这些是你应该绝对知道答案的问题。

6、需求预测和容量规划

需求预测和容量规划简单来说就是保障一个业务有足够的容量和冗余度去服务预测中的未来需求。这里并没有任何特别的概念,但是我们发现行业内有许多团队根本没有这个意识和计划去满足这个要求。一个业务的容量规划,不仅仅要包括自然增长(随着用户使用量上升,资源使用率也上升),也需要包括一些非自然增长的因素(新功能的发布、商业推广,以及其他商业因素在内)。

容量规划有几个步骤是必须的:

必须有一个准确的自然增长需求预测模型,需求预测的时间应该超过资源获取的时间。

这其实是非常简单的,可以使用标尺绘制一个增长图。这不是开玩笑。它有时比一些我见过的花哨的数学模型更准确!

规划中必须有准确的非自然增长的需求来源的统计

广告客户一年中最大的时间是感恩节前一周:每个广告公司都需要花费额外的时间来确保他们的广告在黑色星期五吸引业务。这是“非自然增长需求”的一个很好的例子。

必须有周期性压力测试,以便准确地将系统原始资源信息与业务容量对应起来。

压力测试不需要以整体方式进行,您可以查看正在运行的系统在负载下的行为,以了解其性能,并且您经常得到更好的数字。

重要的是要知道,当你达到边界条件(如 CPU 跑满或达到内存上限)时发生的事情可能会灾难性的,所以有时重要的是要知道这些限制的位置。 

由于容量对可用性至关重要,因此 SRE 团队必须负责容量规划,这意味着他们也必须负责配置。

我从根本上不同意这里的“负责”一词。 SRE 在每个点都完全有资格将任何工作交给另一个团队。关键是我们负责确保容量规划完成并满足业务的要求,但这件事情任何人都可以完成。

我过去曾与一些产品团队合作,他们完成了一个完全合理的容量规划,当然我们也检查了他们的工作。

的确,容量对可用性至关重要。我收到很多工单都是容量方面,我感觉很多曾经出现问题的系统也都是由于子系统容量不足导致。

7、配置

资源的部署与配置是变更管理与容量规划的结合物。在我们的经验里,资源的部署和配置必须能够非常迅速地完成,而且仅仅是在必要的时候才执行,因为资源通常是非常昂贵的。而且这个部署和配置的过程必须要确保能够正确地执行完毕,否则资源就仍然处于不可用状态。增加现有容量经常需要启动新的实例甚至是集群,这通常需要大幅度修改现有的集群配置 ( 配置文件、负载均衡、网络等 ),同时还要执行一系列测试,确保新上线的容量可以正确地服务用户。因此新资源的部署与配置是一个相对比较危险的操作,必须要小心谨慎地执行。

在Google,配置(或Google内部说的“Turn-ups”)可以像更改数字和点击按钮一样简单,也可能是一个高风险需要持续数天的过程。

这里的关键点是如果需要修改配置,应该尽可能无风险无痛苦地进行。

从来没有无风险或无痛苦,我最好的经历是“只有一点风险”和“小的可忍受的痛苦”。当你有这么高的程度或风险和服务,通常是只能由人参与才能完成,无法通过一个简单的 API 调用就自动完成。

我在这里学到的一个教训是:不要试图让计算机模仿人类的配置步骤,如“编辑文件,发送审查,运行脚本,检查控制台”,而是以流动和恒定的方式,“当利用率 > x%,添加 1 个服务器”,“当 1 台新的服务器上线,将它们添加到负载均衡器的后端”。

8、效率和性能

高效地利用各种资源是任何营利性服务都要关心的。因为 SRE 最终负责容量的部署和配置,因此 SRE 必须也承担起任何有关利用率的讨论及改进。因为一个服务的利用率指标通常依赖于这个服务的工作方式以及对容量的配置与部署上。如果能够通过密切关注一 个服务的容量配置策略,进而改进其资源利用率,可以非常有效地降低系统的总成本。

一个业务总体资源的使用情况是由以下几个因素驱动的:用户需求(流量)、可用容量和软件的资源使用效率。SRE 可以通过模型预测用户需求,合理部署和配置可用容量,同时可以改进软件提升资源使用效率。通过这三个因素能够大幅度推动一个服务的效率提升(但是并非全部)。

软件系统一般来说在负载上升的时候,会导致延迟升高。延迟升高其实和容量损失是一样的。当负载到达临界线的时候,一个逐渐变慢的系统最终会停止一切服务。换句话说,系统此时的延迟已经是无穷大了。SRE 的目标是根据一个预设的延迟目标部署和维护足够的容量。SRE 和产品研发团队应该共同监控和优化整个系统的性能,这就相当于给服务增加容量和提升效率了

在阅读这本书之前,如果有人问我“你是否负责二进制版本的性能?”,我的回答也许为否。但我现在完全改变了观点。

系统的可靠性是 SRE 的责任,他们需要防止新的版本导致用户可见的错误,SRE 团队的责任还包括检测,减轻和防止性能退化。 

我的团队在监控和防止新版本的性能退化方面做得还不够,但我们非常关心系统架构,并确保仔细检查新系统的文档说明,以满足一个 SRE 的要求。

小结

站点可靠性工程师(SRE)代表了对行业现存管理大型复杂服务的最佳实践的一个重要突破。由一个简单的想法“我是一个软件工程师,这是我如何来应付重复劳动的办法” 而生,SRE 模型已经发展成一套指导思想,一套方法论,一套激励方法,和一个拥有广阔空间的独立职业。本书的其余部分探讨了 SRE 的详细方法。

这是 SRE 书第 1 章的主要内容,我也谈了自己的一些看法,尽管如此,我们其实只是碰到 SRE 的表面。 到目前为止,我已经表达了什么是 SRE 的工作,有机会我再会解读下一章:『一个 SRE 眼中的 Google 生产环境』 [2]。请留意高可用架构后续发布的文章。

参考链接

  1. https://landing.google.com/sre/book/chapters/introduction.html#googles-approach-to-service-management-site-reliability-engineering-Pasncl

  2. https://landing.google.com/sre/book/chapters/production-environment.html

  3. 『SRE Google 运维解密』英文版在线阅读:https://landing.google.com/sre/book/index.html

高可用架构

改变互联网的构建方式


长按二维码 关注「高可用架构」公众号

原文来自:高可用架构

掌握聚合最新动态了解行业最新趋势
API接口,开发服务,免费咨询服务
新闻动态 > 媒体报道
一个Google SRE工程师眼中的8点运维原则
发布:2017-03-09

我是 Google 一名 SRE (运维)工程师,在过去系列文章中对『SRE: Google 运维解密』一书提出了自己的见解。本文所有见解皆为个人观点,不代表 Google 公司立场。

我们来看书中第一章的一些观点: Google 对运维的解决之道:网站可靠性工程(Site Reliability Engineering)[1]。

虽然每个 SRE 团队都有自己的工作流程、优先级定义以及日常工作规范,但是所有的 SRE 团队都有一套共同的核心方法论。一般来说,SRE 团队要承担以下几类职责:可用性改进,延迟优化,性能优化,效率优化,变更管理,监控,紧急事务处理以及容量规划与管理。SRE 管理层针对这些内容制定了一套完整的沟通准则和行事规范,这些规范规定了 SRE 是如何操作 Google 生产环境的,也规定了 SRE 如何和产品研发部门、测试部门、最终用户进行有效沟通。这些准则和规范能够帮助每一个 SRE 部门保持一个良好的研发、运维工作的平衡。


因此,关键的点是:

SRE 团队要承担以下几类职责:可用性改进,延迟优化,性能优化,效率优化,变更管理,监控,紧急事务处理以及容量规划与管理


线上项目是错综复杂的,如果你只是部署某人的代码,你如何对其服务的响应延迟负责?还好,你有一些标准化的手段,比如使用容量规划、监控并配合变更管理来帮助你。

通常,运维的工作是对系统变慢或不可用的情况负责,从长期来说,需要与开发团队沟通,将潜在的问题修复;从短期来看,有时候运维增加更多的服务器也许反而降低了性能?或者想让程序运行更快反而会降低了可靠性。

下面针对 Google SRE 的 8 大核心原则做一些个人解读。

1、确保长期关注研发工作

如前所述,Google 将 SRE 团队的运维工作限制在 50% 以下。SRE 团队应该将剩余时间花在研发项目上。在实践中,SRE 管理人员应该经常度量团队成员的时间配比,如果有必要的话,采取一些暂时性措施将过多的运维压力转移回开发团队处理。例如说:将生产环境中发现的 Bug 和产生的工单转给研发管理人员去分配,将开发团队成员加入到轮值 on-call 体系中共同承担轮值压力等。这些暂时性措施应该一直持续到运维团队的运维工作压力降低到 50% 以下。在实践中,这种措施实际形成了一个良性循环,激励研发团队设计、构建出不需要人工干预、可以自主运行的系统。只有整个产品部门都认同这个模式,认同 50% 的安全线存在的重要性,才会共同努力避免这种情况的发生。

我在上一篇文章中提到了:我们有管理手段支持回传需求给开发人员,这一做法是 SRE 拥有的一个巨大杠杆。

这里提到的 50% 上限,实际上我在 Google 的任何小组中都没有去精确测量。 在实践中,当有一个团队需要做太多的线上操作工作时,我们会测量具体的工作,例如故障问题数量和提交工单数量。

 下文介绍了这一块是如何工作的。

SRE 处理运维工作的时候的一项准则是:在 8 ~ 12 小时的 on-call 轮值期间最多应该只处理 2 个紧急事件。这个准则保证了 on-call 工程师有足够的时间跟进紧急事件,正确地处理并且恢复服务,并且要撰写一份事后报告。如果一次轮值过程中处理的问题过多,那么每个问题就不可能被详细调查清楚,运维工程师甚至没有时间从中学到任何知识。如果一个小项目无法做到合理报警,规模扩大之后这个情况就会更严重。相对而言,如果一个项目的紧急警报非常少,持续性稳定运行,那么保持这么多 on-call 工程师可能就是在浪费时间。

在 Google,SRE 没有 8 小时的轮班。 我们使用 12/12 轮班或 24 小时轮班。 无论是对 12 小时还是 24 小时班次来说,每个班次“2 次事件”的指标依然适用。 这确保了 24 小时轮班的工程师也有足够的时间来处理他们的事件管理和后续跟进工作。

我不喜欢把这个指标作为平均值。每个班次记录的平均事件数不是我在这里跟踪的:如果每个班次记录的平均数是 0.4,但每月有 4 - 5 天的 3+ 事件,我会认为这是一个不健康的负载,并尝试解决它。 

正常状况是是让每一天需要 SRE 响应的紧急事件都是一个合理的负载,每一个事件都可以被专业地处理。你必须优先处理某一种问题的情况不会发生。

所有的产品事故都应该有对应的事后故障总结,无论有没有触发警报。这里要注意的是,如果一个产品事故没有触发警报,那么事后总结的意义可能更大:因为它将揭示监控系统中的漏洞。

事后故障总结应该包括以下内容:故障发生、发现、解决的全过程,故障的根本原因,预防或者优化的解决方案。

Google 的一项对内准则是“对事不对人”,事后总结的目标是尽早发现和堵住漏洞,而不是通过流程去绕过和掩盖它们。在 SRE 第15章中详细讨论了事后分析。

本周一位同事曾对我说:“今天的故障发生后,我和开发者一起开始了事后总结,他们添加了一段话来解释他们这次变更如何破坏了生产环境,我不得不跟他们聊聊怎么去掉这个描述。

这是因为:如果你专注于找到某人或某事来解释一个故障,那么你就会把自己限制在一个原因里面。在一个故障总结中,你应该列出所有导致故障触发的因素,而不是把它当作一个承认错误的地方。

2、在保障服务 SLO (Service Level Objective) 的前提下最大化迭代速度

产品研发部门和 SRE 之间可以通过消除组织架构冲突来构建良好的合作关系。在企业中,最主要的矛盾就是迭代创新的速度与产品稳定程度之间的矛盾。正如上文所说,其表现形式可能是间接的。在 SRE 模型中,我们选择正面面对这种矛盾,使用的工具是错误预算

我的预算:21分钟

“错误预算”起源于这样一个理念:任何产品都不是也不应该做到 100% 可靠。(显然这个并不适用于心脏起搏器和防抱死刹车系统等)。一般来说,任何软件系统都不应该一味地追求 100% 可靠,因为对最终用户来说,99.999% 和 100% 的可用性是没有实质区别的(99.999% 的可用性是每天 0.6s,每月 26s,每年 5m 的不可用)。从最终用户到服务器之间,有很多中间系统(用户的笔记本电脑、家庭 WiFi、网络提供商和输电线路等)这些系统综合起来可靠性要远低于 99.999%。所以,在 99.999% 和 100% 可靠之间的区别基本上成为其他系统的噪声。就算我们花费巨大精力将系统变为 100% 可靠,也并不能给用户带来任何实质意义上的帮助。

在我在广告 SRE 时,SRE会查看 Google 的广告收入(基于公开发布的收入数据,而不是任何机密信息),并计算每年额外的“9”可用性的价值。这表明有时你确实关心 0.001% 的可用性提升!

如果 100% 不是一个正确的可靠性指标,那么多少才是呢?这其实并不是一个技术问题,而是一个产品问题。要回答这个问题,必须要考虑以下几个方面 :

  • 基于用户的使用习惯,服务可靠性要达到什么程度用户才会满意?

  • 如果这项服务可靠程度不够,用户是否有其他的替代选择?

  • 服务可靠程度是否会影响到用户对这项服务的使用模式?


测试当产品稍微不可靠时,用户的使用会发生什么是很容易做到的:if(user-> in_experiment_set()&& random()< 0.0005),但这不是那种容易让你的经理批准的测试。

公司的商业部门或者是产品部门必须建立起一个合理的可靠性目标。一旦建立,“错误预算”就是“1 - 可靠性目标”。如果一个服务的可靠性目标是 99.99%,那么错误预算就是 0.01%。这意味着产品研发部门和 SRE 部门可以在这个范围内将这个预算用于新功能上线或者产品的创新等任何事情。

尽量不要把错误预算都花在一个地方。

“错误预算”都可以用于什么范畴呢?研发团队需要用这个预算上线新功能,吸引新用户。理想情况下,我们应该使用这个错误预算来最大化新功能上线的速度,同时保障服务质量。这个基本模型建立起来之后,许多常见的战术策略,例如灰度发布,1% A/B 测试等就全说得通了。这些战术策略都是为了更好地使用整个服务的错误预算。

这里介绍了灰度发布的想法:如果推出一个功能,假设它是 20% 不可靠,但只有 5% 的用户可以访问,结果也只有 1% 的中断。 

灰度发布意味着您可以快速发布那些可能存在风险的软件,但也是需要控制在你的全部错误预算内。

通过引进“错误预算”的概念,我们解决了研发团队和 SRE 团队之间的组织架构冲突。SRE 团队的目标不再是“零事故运行”,SRE 团队和产品研发团队目标一致,都是在保障业务服务可靠性需求的同时尽可能地加快功能上线速度。这个改动虽小,意义却很大。一次“生产事故”不再是一件坏事,而是一个创新流程中不可避免的环节,两个团队通过协作共同管理它。

我已经跟开发人员谈过了:“你太小心了,停止多次检查所有细节,那样会导致上线太慢。

3、监控

监控系统是 SRE 团队监控服务质量和可用性的一个主要手段。所以监控系统的设计和策略值得着重讨论。最普遍和传统的报警策略是针对某个特定的情况或者监控值,一旦出现情况或者监控值超过阈值就触发 E-mail 报警。但是这样的报警并不是非常有效:一个需要人工阅读邮件和分析报警来决定目前是否需要采取某种行动的系统从本质上是错误的。监控系统不应该依赖人来分析信息进行报警,而是应该由系统自动分析,仅仅当需要用户执行某种操作时,才需要通知用户。

在 Google 有一个规则:没有不需要采取行动的警报。如果您遇到一个自己认为不需要执行操作的警报,您需要采用自动化的手段来修复该警报。

以下是各种我认为值得推荐的做法:

  • 明确修复的责任,并跟进相关团队。

  • 提交 bug 并跟踪记录为什么会这样的问题。

  • 教育某人用更好的方式来完成,避免出现报警的情况。

  • 更新已有的 bug,输出更多调试信息。

  • 调整警报阈值,避免用户并没有出现访问问题时候发送报警。

  • 删除那些无效警报,因为它是无用的和不相关的。

监控不做任何事情是不可能的,有三种有效的监控输出:

警报

意味着收到警报的用户需要立即执行某种操作,目标是解决某种已经发生的问题,或者是避免即将要发生的问题。

这使我所拥有的每个设备都会产生大量的噪音。如果我在 5 分钟内没有回应,它会找到我的替代者,他的工作是采取行动。

我所在的 SRE 团队有一个送花规则,如果问题落到替代者来处理,这对主负责人来说是个悲剧,你将需要给替代者送去花和一张卡。

工单

意味着接受工单的用户应该执行某种操作,但是并非立即执行。系统并不能自动解决目前的情况,但是如果一个用户在几天内执行这项操作,系统不会受到任何影响。


当我 oncall 轮值时,我能每天检查四次工单队列就很不错了。他们重要但不紧急,而且通常也是超级耗时的问题,因为他们需要大量的分析来解释发生的原因。 “为什么我们今天比一周前增加了 25% 的磁盘 I/O,并且达到了吞吐量限制?”


日志

平时没有人需要关注日志信息,但是日志信息依然被收集起来以备调试和事后分析时使用。正确的做法是平时没有人主动阅读日志,除非处理其他请求的时候被要求这么做。

我要指出,下次有人如果试图实现更多的“严重:电子邮件”警报,所有收到的都将是无用的噪音。


4、紧急事件处理

可靠性是 MTTF(平均失败时间)和 MTTR(平均恢复时间)的结合结果。评价一个团队将系统恢复到正常情况的最有效指标,就是 MTTR

任何需要人工操作的事情,都只会延长恢复时间。相比之下,一个可以自动化恢复的系统即使有更多的故障发生,也要比事事都需要人工干预的系统可用性更高。当人工介入不可避免的时候,我们也发现与“车到山前必有路”的态度相比,通过事先预案并且将最佳方法记录在“运维手册”上通常会使 MTTR 降低 3 倍以上。初期几个万能的工程师的确可以解决生产问题,但是长久看来一个手持“运维宝典”经过多次训练的 on-call 工程师才是正确之路。虽然不论多么完备的“运维手册”也无法替代人的创新思维,但是在巨大的时间压力和产品压力下,运维手册中记录的清晰调试步骤和分析方法对处理问题的人是不可或缺的。因此,Google SRE 将大部分重心放在“运维手册”的维护上,同时通过“Wheel of Misfortune”等项目培训团队成员。

通过事先预案并且将最佳方法记录在“运维手册”上通常会使 MTTR 降低 3 倍以上!

运维手册的质量差别也是千差万别。从“这样过时的字在这里没有什么意义的”,到“这本手册将需要我 45 分钟阅读,并且重要的信息被埋在一个段落的末尾附近的链接”到“这本手册告诉我如何诊断和解决第一句中的问题“。

不同团队对运维手册有很多不同的看法。一种看法是你应该非常熟悉你所有的操作,因此你不需要手册,你需要的是一个精确的监视控制台,以便你知道采取什么行动。

没有手册是一个奢侈的事情,只有在团队需要支持的事情很少的情况下可行。我们这些支持很多系统的人不能将所有内容全部放入脑子。

相比之下,我个人的意见是,如果手册无用,也不是警报,就应该重建它,或删除警报和手册。因为没有足够有用的背景信息的警报是如此危险。

5、变更管理

SRE 经验告诉我们,大概 70% 的生产事故由某种部署的变更而触发。变更管理的最佳实践可使用自动化来完成以下几个项目:

  • 采用渐进式发布机制。

  • 迅速而准确地检测到问题的发生。

  • 当出现问题时,安全迅速地回退改动。

    这三点可以有效地降低变更给 SRE 和最终用户带来的时间成本和服务质量的下降。通过将人工因素排除在流程之外,这些操作将不再受到经常发生在人身上的“狼来了”思想以及对大量重复性劳动的关注疲劳所影响。于是,变更执行的速度和安全性同时得到了提高。

这部分内容较少,我相信其他章节会谈到这一点,但我要在这里做出强调:70% 的生产事故由某种部署的变更而触发。70% 的故障可以通过不做任何事情来避免!我们是自己的敌人。

因此,可以将错误预算支出降低高达 70% 的基本工具是:及时发现上线出现问题并快速回滚。这是一个多么简单的事情!你需要多长时间才能注意到这是一个有问题的版本发布?回滚它需要多长时间?在回滚完成之前,它影响了多少人?

这些是你应该绝对知道答案的问题。

6、需求预测和容量规划

需求预测和容量规划简单来说就是保障一个业务有足够的容量和冗余度去服务预测中的未来需求。这里并没有任何特别的概念,但是我们发现行业内有许多团队根本没有这个意识和计划去满足这个要求。一个业务的容量规划,不仅仅要包括自然增长(随着用户使用量上升,资源使用率也上升),也需要包括一些非自然增长的因素(新功能的发布、商业推广,以及其他商业因素在内)。

容量规划有几个步骤是必须的:

必须有一个准确的自然增长需求预测模型,需求预测的时间应该超过资源获取的时间。

这其实是非常简单的,可以使用标尺绘制一个增长图。这不是开玩笑。它有时比一些我见过的花哨的数学模型更准确!

规划中必须有准确的非自然增长的需求来源的统计

广告客户一年中最大的时间是感恩节前一周:每个广告公司都需要花费额外的时间来确保他们的广告在黑色星期五吸引业务。这是“非自然增长需求”的一个很好的例子。

必须有周期性压力测试,以便准确地将系统原始资源信息与业务容量对应起来。

压力测试不需要以整体方式进行,您可以查看正在运行的系统在负载下的行为,以了解其性能,并且您经常得到更好的数字。

重要的是要知道,当你达到边界条件(如 CPU 跑满或达到内存上限)时发生的事情可能会灾难性的,所以有时重要的是要知道这些限制的位置。 

由于容量对可用性至关重要,因此 SRE 团队必须负责容量规划,这意味着他们也必须负责配置。

我从根本上不同意这里的“负责”一词。 SRE 在每个点都完全有资格将任何工作交给另一个团队。关键是我们负责确保容量规划完成并满足业务的要求,但这件事情任何人都可以完成。

我过去曾与一些产品团队合作,他们完成了一个完全合理的容量规划,当然我们也检查了他们的工作。

的确,容量对可用性至关重要。我收到很多工单都是容量方面,我感觉很多曾经出现问题的系统也都是由于子系统容量不足导致。

7、配置

资源的部署与配置是变更管理与容量规划的结合物。在我们的经验里,资源的部署和配置必须能够非常迅速地完成,而且仅仅是在必要的时候才执行,因为资源通常是非常昂贵的。而且这个部署和配置的过程必须要确保能够正确地执行完毕,否则资源就仍然处于不可用状态。增加现有容量经常需要启动新的实例甚至是集群,这通常需要大幅度修改现有的集群配置 ( 配置文件、负载均衡、网络等 ),同时还要执行一系列测试,确保新上线的容量可以正确地服务用户。因此新资源的部署与配置是一个相对比较危险的操作,必须要小心谨慎地执行。

在Google,配置(或Google内部说的“Turn-ups”)可以像更改数字和点击按钮一样简单,也可能是一个高风险需要持续数天的过程。

这里的关键点是如果需要修改配置,应该尽可能无风险无痛苦地进行。

从来没有无风险或无痛苦,我最好的经历是“只有一点风险”和“小的可忍受的痛苦”。当你有这么高的程度或风险和服务,通常是只能由人参与才能完成,无法通过一个简单的 API 调用就自动完成。

我在这里学到的一个教训是:不要试图让计算机模仿人类的配置步骤,如“编辑文件,发送审查,运行脚本,检查控制台”,而是以流动和恒定的方式,“当利用率 > x%,添加 1 个服务器”,“当 1 台新的服务器上线,将它们添加到负载均衡器的后端”。

8、效率和性能

高效地利用各种资源是任何营利性服务都要关心的。因为 SRE 最终负责容量的部署和配置,因此 SRE 必须也承担起任何有关利用率的讨论及改进。因为一个服务的利用率指标通常依赖于这个服务的工作方式以及对容量的配置与部署上。如果能够通过密切关注一 个服务的容量配置策略,进而改进其资源利用率,可以非常有效地降低系统的总成本。

一个业务总体资源的使用情况是由以下几个因素驱动的:用户需求(流量)、可用容量和软件的资源使用效率。SRE 可以通过模型预测用户需求,合理部署和配置可用容量,同时可以改进软件提升资源使用效率。通过这三个因素能够大幅度推动一个服务的效率提升(但是并非全部)。

软件系统一般来说在负载上升的时候,会导致延迟升高。延迟升高其实和容量损失是一样的。当负载到达临界线的时候,一个逐渐变慢的系统最终会停止一切服务。换句话说,系统此时的延迟已经是无穷大了。SRE 的目标是根据一个预设的延迟目标部署和维护足够的容量。SRE 和产品研发团队应该共同监控和优化整个系统的性能,这就相当于给服务增加容量和提升效率了

在阅读这本书之前,如果有人问我“你是否负责二进制版本的性能?”,我的回答也许为否。但我现在完全改变了观点。

系统的可靠性是 SRE 的责任,他们需要防止新的版本导致用户可见的错误,SRE 团队的责任还包括检测,减轻和防止性能退化。 

我的团队在监控和防止新版本的性能退化方面做得还不够,但我们非常关心系统架构,并确保仔细检查新系统的文档说明,以满足一个 SRE 的要求。

小结

站点可靠性工程师(SRE)代表了对行业现存管理大型复杂服务的最佳实践的一个重要突破。由一个简单的想法“我是一个软件工程师,这是我如何来应付重复劳动的办法” 而生,SRE 模型已经发展成一套指导思想,一套方法论,一套激励方法,和一个拥有广阔空间的独立职业。本书的其余部分探讨了 SRE 的详细方法。

这是 SRE 书第 1 章的主要内容,我也谈了自己的一些看法,尽管如此,我们其实只是碰到 SRE 的表面。 到目前为止,我已经表达了什么是 SRE 的工作,有机会我再会解读下一章:『一个 SRE 眼中的 Google 生产环境』 [2]。请留意高可用架构后续发布的文章。

参考链接

  1. https://landing.google.com/sre/book/chapters/introduction.html#googles-approach-to-service-management-site-reliability-engineering-Pasncl

  2. https://landing.google.com/sre/book/chapters/production-environment.html

  3. 『SRE Google 运维解密』英文版在线阅读:https://landing.google.com/sre/book/index.html

高可用架构

改变互联网的构建方式


长按二维码 关注「高可用架构」公众号

原文来自:高可用架构

电话 0512-88869195