SRE 理解
概述
SRE(Site Reliability Engineering)翻译成中文就是网站稳定性工程师,专门负载网站的稳定运行。说到这个职责可能很多人会联想到运维工程师,两者确实有相似之处,但是也不尽然。SRE本质上还是软件工程师,招聘时按照软件开发工程师的要求来招聘,通过软件工程理论来管理工程,力图重新定义运维,推进业务进化。
SRE的概念最早由谷歌提出,其他互联网公司争相跟进,目前实践的比较好的是谷歌和奈飞(neflix)。奈飞的核心SRE据说只有个位数,他们运营着全球190国家的上亿用户,用实践证明了SRE理论的正确性。
站点可靠性工程师(SRE)代表了对行业现存管理大型复杂服务的最佳实践的一个重要突破。由一个简单的想法“我是一个软件工程师,这是我如何来应付重复劳动的办法” 而生,SRE模型已经发展成一套指导思想,一套方法论,一套激励方法,和一个拥有广阔空间的独立职业。
SRE 和 DevOps
站点可靠性工程的核心,就是对 DevOps 范例的实践。DevOps 的定义有很多种方式。开发团队(“dev”)和运维(“ops”)团队相互分离的传统模式下,写代码的团队在将服务交付给用户使用之后就不再对服务状态负责了。开发团队“把代码扔到墙那边”让运维团队去部署和支持。
这种情况会导致大量失衡。开发和运维的目标总是不一致 —— 开发希望用户体验到“最新最棒”的代码,但是运维想要的是变更尽量少的稳定系统。运维是这样假定的,任何变更都可能引发不稳定,而不做任何变更的系统可以一直保持稳定。(减少软件的变更次数并不是避免故障的唯一因素,认识到这一点很重要。例如,虽然你的 web 应用保持不变,但是当用户数量涨到十倍时,服务可能就会以各种方式出问题。)
DevOps 理念认为通过合并这两个岗位就能够消灭争论。如果开发团队时刻都想把新代码部署上线,那么他们也必须对新代码引起的故障负责。就像亚马逊的 Werner Vogels 说的那样,“谁开发,谁运维”(生产环境)。但是开发人员已经有一大堆问题了。他们不断的被推动着去开发老板要的产品功能。再让他们去了解基础设施,包括如何部署、配置还有监控服务,这对他们的要求有点太多了。所以就需要 SRE 了。
开发一个 web 应用的时候经常是很多人一起参与。有用户界面设计师、图形设计师、前端工程师、后端工程师,还有许多其他工种(视技术选型的具体情况而定)。如何管理写好的代码也是需求之一(例如部署、配置、监控)—— 这是 SRE 的专业领域。但是,就像前端工程师受益于后端领域的知识一样(例如从数据库获取数据的方法),SRE 理解部署系统的工作原理,知道如何满足特定的代码或者项目的具体需求。
所以 SRE 不仅仅是“写代码的运维工程师”。相反,SRE 是开发团队的成员,他们有着不同的技能,特别是在发布部署、配置管理、监控、指标等方面。但是,就像前端工程师必须知道如何从数据库中获取数据一样,SRE 也不是只负责这些领域。为了提供更容易升级、管理和监控的产品,整个团队共同努力。
当一个团队在做 DevOps 实践,但是他们意识到对开发的要求太多了,过去由运维团队做的事情,现在需要一个专家来专门处理。这个时候,对 SRE 的需求很自然地就出现了。
SRE职责
SRE的职责是什么的?SRE的工作内容主要包括以下内容
- 容量规划
- 生产系统监控报警
- 部署,发布变更
- 值班
而SRE最明确的职责就是确保站点的稳定,这需要他对站点所涉及的系统、组件非常熟悉(大型网站的系统和组件依赖以及网站的发展史会在后面的文章给大家介绍),同时需要开发、维护很多工具和系统支撑其完成这项工作,比如devops系统,监控系统,日志系统,资源管理系统等。总的来说,SRE是一个综合素质很高的全能手,需要懂服务器、操作系统、网络、中间件…具备基础编程能力、架构能力、问题分析能力、抗压能力以及性能调优能力。
SRE在初创公司怎么工作
如果你们公司有好几百位员工,那是非常好的(如果到了 Google 和 Facebook 的规模就更不用说了)。大公司的 SRE 团队分散在各个开发团队里。但是一个初创公司没有这种规模经济,工程师经常身兼数职。那么小公司该让谁做 SRE 呢?其中一种方案是完全践行 DevOps,那些大公司里属于 SRE 的典型任务,在小公司就让开发者去负责。另一种方案,则是聘请专家 —— 也就是 SRE。
让开发人员做 SRE 最显著的优点是,团队规模变大的时候也能很好的扩展。而且,开发人员将会全面地了解应用的特性。但是,许多初创公司的基础设施包含了各种各样的 SaaS 产品,这种多样性在基础设施上体现的最明显,因为连基础设施本身也是多种多样。然后你们在某个基础设施上引入指标系统、站点监控、日志分析、容器等等。这些技术解决了一部分问题,也增加了复杂度。开发人员除了要了解应用程序的核心技术(比如开发语言),还要了解上述所有技术和服务。最终,掌握所有的这些技术让人无法承受。
另一种方案是聘请专家专职做 SRE。他们专注于发布部署、配置管理、监控和指标,可以节省开发人员的时间。这种方案的缺点是,SRE 的时间必须分配给多个不同的应用(就是说 SRE 需要贯穿整个工程部门)。 这可能意味着 SRE 没时间对任何应用深入学习,然而他们可以站在一个能看到服务全貌的高度,知道各个部分是怎么组合在一起的。 这个“三万英尺高的视角”可以帮助 SRE 从系统整体上考虑,哪些薄弱环节需要优先修复。
有一个关键信息我还没提到:其他的工程师。他们可能很渴望了解发布部署的原理,也很想尽全力学会使用指标系统。而且,雇一个 SRE 可不是一件简单的事儿。因为你要找的是一个既懂系统管理又懂软件工程的人。(我之所以明确地说软件工程而不是说“能写代码”,是因为除了写代码之外软件工程还包括很多东西,比如编写良好的测试或文档。)
因此,在某些情况下让开发人员做SRE可能更合理一些。如果这样做了,得同时关注代码和基础设施(购买 SaaS 或内部自建)的复杂程度。这两边的复杂性,有时候能促进专业化。
一个Google SRE工程师眼中的八点运维原则
一、确保长期关注研发工作
如前所述,Google 将 SRE 团队的运维工作限制在 50% 以下。SRE 团队应该将剩余时间花在研发项目上
这里提到的 50% 上限,实际上我在 Google 的任何小组中都没有去精确测量。 在实践中,当有一个团队需要做太多的线上操作工作时,我们会测量具体的工作,例如故障问题数量和提交工单数量。
SRE 处理运维工作的时候的一项准则是:在 8 ~ 12 小时的 on-call 轮值期间最多应该只处理 2 个紧急事件
所有的产品事故都应该有对应的事后故障总结:
Google 的一项对内准则是“对事不对人”,事后总结的目标是尽早发现和堵住漏洞,而不是通过流程去绕过和掩盖它们。在 SRE 第15章中详细讨论了事后分析。
如果专注于找到某人或某事来解释一个故障,那么就会把自己限制在一个原因里面。在一个故障总结中,应该列出所有导致故障触发的因素,而不是把它当作一个承认错误的地方
二、在保障服务 SLO (Service Level Objective) 的前提下最大化迭代速度
产品研发部门和 SRE 之间可以通过消除组织架构冲突来构建良好的合作关系。在企业中,最主要的矛盾就是迭代创新的速度与产品稳定程度之间的矛盾。正如上文所说,其表现形式可能是间接的。在 SRE 模型中,我们选择正面面对这种矛盾,使用的工具是错误预算
我的预算:21分钟。
“错误预算”起源于这样一个理念:任何产品都不是也不应该做到 100% 可靠
SRE会查看 Google 的广告收入(基于公开发布的收入数据,而不是任何机密信息),并计算每年额外的“9”可用性的价值。这表明有时你确实关心 0.001% 的可用性提升!
如果 100% 不是一个正确的可靠性指标,那么多少才是呢?这其实并不是一个技术问题,而是一个产品问题。要回答这个问题,必须要考虑以下几个方面 :
- 基于用户的使用习惯,服务可靠性要达到什么程度用户才会满意?
- 如果这项服务可靠程度不够,用户是否有其他的替代选择?
- 服务可靠程度是否会影响到用户对这项服务的使用模式?
测试当产品稍微不可靠时,用户的使用会发生什么是很容易做到的:if(user-> in_experiment_set&& random< 0.0005),但这不是那种容易让你的经理批准的测试。
公司的商业部门或者是产品部门必须建立起一个合理的可靠性目标。一旦建立,“错误预算”就是“1 - 可靠性目标”。如果一个服务的可靠性目标是 99.99%,那么错误预算就是 0.01%。这意味着产品研发部门和 SRE 部门可以在这个范围内将这个预算用于新功能上线或者产品的创新等任何事情。
尽量不要把错误预算都花在一个地方。
image.png
“错误预算”都可以用于什么范畴呢?研发团队需要用这个预算上线新功能,吸引新用户。理想情况下,我们应该使用这个错误预算来最大化新功能上线的速度,同时保障服务质量。这个基本模型建立起来之后,许多常见的战术策略,例如灰度发布,1% A/B 测试等就全说得通了。这些战术策略都是为了更好地使用整个服务的错误预算。
这里介绍了灰度发布的想法:如果推出一个功能,假设它是 20% 不可靠,但只有 5% 的用户可以访问,结果也只有 1% 的中断。
灰度发布意味着您可以快速发布那些可能存在风险的软件,但也是需要控制在你的全部错误预算内。
通过引进“错误预算”的概念,我们解决了研发团队和 SRE 团队之间的组织架构冲突。SRE 团队的目标不再是“零事故运行”,SRE 团队和产品研发团队目标一致,都是在保障业务服务可靠性需求的同时尽可能地加快功能上线速度。这个改动虽小,意义却很大。一次“生产事故”不再是一件坏事,而是一个创新流程中不可避免的环节,两个团队通过协作共同管理它。
开发人员:“你太小心了,停止多次检查所有细节,那样会导致上线太慢。
三、监控
监控系统是SRE团队监控服务质量和可用性的一个主要手段。所以监控系统的设计和策略值得着重讨论。最普遍和传统的报警策略是针对某个特定的情况或者监控值,一旦出现情况或者监控值超过阈值就触发 E-mail 报警。但是这样的报警并不是非常有效:一个需要人工阅读邮件和分析报警来决定目前是否需要采取某种行动的系统从本质上是错误的
在 Google 有一个规则:没有不需要采取行动的警报。 如果您遇到一个自己认为不需要执行操作的警报,您需要采用自动化的手段来修复该警报。
以下是各种值得推荐的做法:
- 明确修复的责任,并跟进相关团队。
- 提交 bug 并跟踪记录为什么会这样的问题。
- 教育某人用更好的方式来完成,避免出现报警的情况。
- 更新已有的 bug,输出更多调试信息。
- 调整警报阈值,避免用户并没有出现访问问题时候发送报警。
- 删除那些无效警报,因为它是无用的和不相关的。
监控不做任何事情是不可能的,有三种有效的监控输出:
警报
意味着收到警报的用户需要立即执行某种操作,目标是解决某种已经发生的问题,或者是避免即将要发生的问题。
这使我所拥有的每个设备都会产生大量的噪音。如果我在 5 分钟内没有回应,它会找到我的替代者,他的工作是采取行动。
我所在的 SRE 团队有一个送花规则,如果问题落到替代者来处理,这对主负责人来说是个悲剧,你将需要给替代者送去花和一张卡。
工单
意味着接受工单的用户应该执行某种操作,但是并非立即执行。系统并不能自动解决目前的情况,但是如果一个用户在几天内执行这项操作,系统不会受到任何影响。
当我 oncall 轮值时,我能每天检查四次工单队列就很不错了。他们重要但不紧急,而且通常也是超级耗时的问题,因为他们需要大量的分析来解释发生的原因。 “为什么我们今天比一周前增加了 25% 的磁盘 I/O,并且达到了吞吐量限制?”
日志
平时没有人需要关注日志信息,但是日志信息依然被收集起来以备调试和事后分析时使用。正确的做法是平时没有人主动阅读日志,除非处理其他请求的时候被要求这么做。
下次有人如果试图实现更多的“严重:电子邮件”警报,所有收到的都将是无用的噪音。
四、紧急事件处理
可靠性是 MTTF(平均失败时间)和 MTTR(平均恢复时间)的结合结果。评价一个团队将系统恢复到正常情况的最有效指标,就是 MTTR
任何需要人工操作的事情,都只会延长恢复时间通过事先预案并且将最佳方法记录在“运维手册”上通常会使 MTTR 降低 3 倍以上
通过事先预案并且将最佳方法记录在“运维手册”上通常会使 MTTR 降低 3 倍以上!
运维手册的质量差别也是千差万别。从“这样过时的字在这里没有什么意义的”,到“这本手册将需要我 45 分钟阅读,并且重要的信息被埋在一个段落的末尾附近的链接”到“这本手册告诉我如何诊断和解决第一句中的问题“。
不同团队对运维手册有很多不同的看法。一种看法是你应该非常熟悉你所有的操作,因此你不需要手册,你需要的是一个精确的监视控制台,以便你知道采取什么行动。
没有手册是一个奢侈的事情,只有在团队需要支持的事情很少的情况下可行。我们这些支持很多系统的人不能将所有内容全部放入脑子。
相比之下,如果手册无用,也不是警报,就应该重建它,或删除警报和手册。因为没有足够有用的背景信息的警报是如此危险。
五、变更管理
SRE 经验告诉我们,大概 70% 的生产事故由某种部署的变更而触发。变更管理的最佳实践可使用自动化来完成以下几个项目:
- 采用渐进式发布机制。
- 迅速而准确地检测到问题的发生。
- 当出现问题时,安全迅速地回退改动。
这三点可以有效地降低变更给 SRE 和最终用户带来的时间成本和服务质量的下降。通过将人工因素排除在流程之外,这些操作将不再受到经常发生在人身上的“狼来了”思想以及对大量重复性劳动的关注疲劳所影响。于是,变更执行的速度和安全性同时得到了提高。
这部分内容较少,我相信其他章节会谈到这一点,但我要在这里做出强调:70% 的生产事故由某种部署的变更而触发。 70% 的故障可以通过不做任何事情来避免!我们是自己的敌人。
因此,可以将错误预算支出降低高达 70% 的基本工具是:及时发现上线出现问题并快速回滚。 这是一个多么简单的事情!你需要多长时间才能注意到这是一个有问题的版本发布?回滚它需要多长时间?在回滚完成之前,它影响了多少人?
六、需求预测和容量规划
需求预测和容量规划简单来说就是保障一个业务有足够的容量和冗余度去服务预测中的未来需求。这里并没有任何特别的概念,但是我们发现行业内有许多团队根本没有这个意识和计划去满足这个要求。一个业务的容量规划,不仅仅要包括自然增长(随着用户使用量上升,资源使用率也上升),也需要包括一些非自然增长的因素(新功能的发布、商业推广,以及其他商业因素在内)。
容量规划有几个步骤是必须的:
- 必须有一个准确的自然增长需求预测模型
这其实是非常简单的,可以使用标尺绘制一个增长图。这不是开玩笑。它有时比一些我见过的花哨的数学模型更准确!
- 规划中必须有准确的非自然增长的需求来源的统计
广告客户一年中最大的时间是感恩节前一周:每个广告公司都需要花费额外的时间来确保他们的广告在黑色星期五吸引业务。这是“非自然增长需求”的一个很好的例子
- 必须有周期性压力测试
压力测试不需要以整体方式进行,您可以查看正在运行的系统在负载下的行为,以了解其性能,并且您经常得到更好的数字。
重要的是要知道,当你达到边界条件(如 CPU 跑满或达到内存上限)时发生的事情可能会灾难性的,所以有时重要的是要知道这些限制的位置。
- 由于容量对可用性至关重要,因此 SRE 团队必须负责容量规划,这意味着他们也必须负责配置
SRE 在每个点都完全有资格将任何工作交给另一个团队。关键是我们负责确保容量规划完成并满足业务的要求,但这件事情任何人都可以完成。
的确,容量对可用性至关重要。我收到很多工单都是容量方面,我感觉很多曾经出现问题的系统也都是由于子系统容量不足导致。
七、配置
资源的部署与配置是变更管理与容量规划的结合物。在我们的经验里,资源的部署和配置必须能够非常迅速地完成,而且仅仅是在必要的时候才执行,因为资源通常是非常昂贵的。而且这个部署和配置的过程必须要确保能够正确地执行完毕,否则资源就仍然处于不可用状态。增加现有容量经常需要启动新的实例甚至是集群,这通常需要大幅度修改现有的集群配置 ( 配置文件、负载均衡、网络等 ),同时还要执行一系列测试,确保新上线的容量可以正确地服务用户。因此新资源的部署与配置是一个相对比较危险的操作,必须要小心谨慎地执行。
在Google,配置(或Google内部说的“Turn-ups”)可以像更改数字和点击按钮一样简单,也可能是一个高风险需要持续数天的过程。
这里的关键点是如果需要修改配置,应该尽可能无风险无痛苦地进行。
从来没有无风险或无痛苦,我最好的经历是“只有一点风险”和“小的可忍受的痛苦”。当你有这么高的程度或风险和服务,通常是只能由人参与才能完成,无法通过一个简单的 API 调用就自动完成。
我在这里学到的一个教训是:不要试图让计算机模仿人类的配置步骤,如“编辑文件,发送审查,运行脚本,检查控制台”,而是以流动和恒定的方式,“当利用率 > x%,添加 1 个服务器”,“当 1 台新的服务器上线,将它们添加到负载均衡器的后端”。
八、效率和性能
高效地利用各种资源是任何营利性服务都要关心的。因为 SRE 最终负责容量的部署和配置,因此 SRE 必须也承担起任何有关利用率的讨论及改进。因为一个服务的利用率指标通常依赖于这个服务的工作方式以及对容量的配置与部署上。如果能够通过密切关注一 个服务的容量配置策略,进而改进其资源利用率,可以非常有效地降低系统的总成本。
一个业务总体资源的使用情况是由以下几个因素驱动的:用户需求(流量)、可用容量和软件的资源使用效率。SRE 可以通过模型预测用户需求,合理部署和配置可用容量,同时可以改进软件提升资源使用效率。通过这三个因素能够大幅度推动一个服务的效率提升(但是并非全部)。
软件系统一般来说在负载上升的时候,会导致延迟升高。延迟升高其实和容量损失是一样的。当负载到达临界线的时候,一个逐渐变慢的系统最终会停止一切服务。换句话说,系统此时的延迟已经是无穷大了。SRE 的目标是根据一个预设的延迟目标
系统的可靠性是 SRE 的责任,他们需要防止新的版本导致用户可见的错误,SRE 团队的责任还包括检测,减轻和防止性能退化。
文章转载自:
10分钟了解谷歌SRE
第一篇 - SRE闲谈
SRE:谷歌运维解密
Google SRE 中文版.pdf
一个Google SRE工程师眼中的8点运维原则
我所理解的SRE、PE和应用运维(下)
什么是 SRE?它和 DevOps 是怎么关联的?