1.2 可靠性栈概述
如果我们接受可靠性是服务最重要的指标,用户决定可靠性,不总是完美的也没有关系,那么我们需要一种能够涵盖1.1节中三个真理的思维方式。你可以花费的资源是有限的,无论是财务、人力还是政治资源,而考虑这些资源的最好方法之一就是通过我所说的可靠性栈。这是本书的主要内容。图1-1显示了可靠性栈的基本构建块,我们将从关键术语的简单概述开始,这样可以保证我们有一致的理解。
在可靠性栈的底部有服务等级指标(SLI)。SLI是通过度量服务的某些指标或者一段数据来确定的量化指标。一个好的SLI是从用户的角度来度量服务。它可能表示用户是否可以足够快地加载网页。人们喜欢加载速度快的网站,但也不是说用户需要网站必须瞬间加载完。如果SLI可以为每个事件产生一个“好”或“坏”的结果,“是的,这个服务做了用户需要它做的事”或者“不,这个服务没有做用户需要它做的事”,那么SLI最有用。例如,你的研究可以确定只要网页在2s内加载,用户就会很开心。那么你就可以说,任何页面加载时间小于或等于2s都是“好”,任何大于2s的页面加载时间都是“坏”。
图1-1:可靠性栈的基本构建块
一旦有了一个可以将SLI转换为“好”或“坏”值的系统,就可以通过将SLI除以事件总数来轻松确定“好”事件的百分比。例如,假设一天内有60000名访问者访问你的站点,你可以测量其中59982次访问在2s内加载页面。你可以将“好”的访问量除以总访问量得到一个百分比来表示用户能够快速加载网页的概率:
该栈的上一级是SLO,它是根据SLI来设置的。你已经了解了如何将总事件中的好事件的数量转换为百分比。SLO就是这个百分比应达到的目标。SLO是服务所针对的“适当的可靠性水平”。继续我们的示例,如果你将网页快速加载成功率设置为99.97%而没有听到任何抱怨,那么你可以推断,只要99.97%的页面加载足够快,用户就满意了。然而,除此之外还有很多需要考虑的方面。第4章将介绍如何选择好的SLO。
在Site Reliability Engineering(O’Reilly)[1]一书中,SLI被定义为“对所提供的服务等级的某些方面仔细定义的定量度量”。在Site Reliability Engineering一书中,它们通常被定义为良好事件除以总事件的比率。在本书中,我们采取了一种更细致的方法。整个系统从度量开始,应用一些阈值或者聚合它们,将事物分为“好”值和“坏”值,将这些值转换为百分比,然后将该百分比与目标值进行比较。对于每个组织来说,具体如何实现这一点并不相同。这将在很大程度上取决于可用的度量或度量方法的种类、如何存储和分析它们、它们的数量和质量,以及你可以在系统的何处执行必要的数学运算。对于如何在SLI和SLO之间划清界限的问题,没有统一的答案,但事实证明,只要你在自己的组织中使用相同的定义,这些问题并不重要。我们将在本书后面更详细地讨论这些细微差别。
最后,在栈的顶部,我们有错误预算(error budget),这些预算由SLO决定。错误预算是一种在一段时间内根据SLO来测量SLI如何执行的方法。它定义了在该期间内允许你的服务有多不可靠,并作为何时你需要采取纠正措施的信号。能找出你目前是否达到了SLO是一回事,而能报告你在一天、一周、一个月、一个季度甚至一年内如何实现这个目标则是另一回事。然后,你可以使用这些信息进行讨论并决定如何为接下来的工作设置优先级。例如,如果你一个月内用尽了错误预算,则可能会专门安排一名工程师改进冲刺阶段的可靠性,但如果你耗尽了一个季度的错误预算,那么也许是时候该让大家都专注于解决让服务变得更可靠的问题。第5章将对这些内容进行深入的讨论。
你可能还听说过服务等级协议(SLA),如图1-2所示。它们通常由与你的SLO相同或至少相似的SLI来驱动,并且通常也有自己的错误预算。SLA与SLO非常相似,但在一些重要方面有所不同。
图1-2:SLA由SLI决定
SLA是写在与付费客户的合同中的业务决策。有时,你可能还会在公司内部看到它们,这些公司足够大,能够在组织或团队之间建立收费系统。它们有明确的承诺,包括付款。
SLO是一个目标百分比,用来帮助你推动决策,而SLA通常是对客户的承诺,其中包括如果你没有达到目标会给予某种补偿。如果你违反了SLO,那么将生成一段用于考虑服务可靠性的数据。如果你在一段时间内违反了一个SLO,那么你可以选择做些什么。如果你违反了你的SLA,那么你就违反了你对客户的承诺(你需要根据承诺做出相应的补偿)。如果你在一段时间内违反了SLA,那么你通常没有太多的选择来决定如何以及何时对其采取行动,你需要及时做出响应,否则你可能无法长时间维持业务。
SLA在这里没有详细介绍。为有效的业务开发和管理SLA不在本书的讨论范围之内。本书重点介绍围绕SLO的可靠性栈元素,以及如何使用这些数据在组织或公司内进行更好的讨论和做出更好的决策。
1.2.1 SLI
SLI是可靠性栈中最重要的一部分,是本书中很重要的概念。你可能永远无法获得合理的SLO或计算出来的错误预算,从而做出决策。但是退后一步,从用户的角度考虑你的服务,对于你的团队、你的组织或你的公司如何看待可靠性可能是一个分水岭。SLI是功能强大的数据集,它可以帮助你处理所有事情,从对实际重要的事情发出告警到在事件响应期间推动调试工作,所有这些都是因为它们是考虑到实际用户体验的度量方法。
从最基本的角度来说,一个有意义的SLI只是一个从用户的角度告诉你服务如何运行的度量。尽管起点可能包括API可用性或错误率等因素,但更好的SLI度量是比如用户是否可以用你的服务进行身份验证并及时从中检索数据。这是因为我们需要考虑整个用户的使用体验。第3章将更深入地讨论这一点。
一个好的SLI也可以用所有利益相关者都能理解的句子来表达。正如我们稍后将要讨论的,对于复杂的服务,通知SLI状态的数学公式可能会变得相当复杂。然而,一个正确的SLI定义必须能够被广大读者理解。第15章将更多地讨论定义、可理解性和可发现性的重要性。
1.2.2 SLO
正如已经提到的,而且以后还会被提到很多次,试图确保任何事情都100%可靠是愚蠢的。我们总会遇到服务故障、系统发生错误、意外事故或人为导致的故障。任何服务都有依赖,所以即使你能确保你的服务99.999%的时间是可靠的,但是如果你所依赖的某些东西的可靠性比你的服务小,那么用户可能根本不知道你的系统的特定部分是否一开始就在正常运行。“某些东西”甚至不一定是你的服务硬性依赖的,它可以是用户关键路径上的任何东西。例如,如果你的大多数用户依赖于消费者级的互联网连接,那么你所能做的任何事情都不会使你的服务看起来比这些互联网连接的服务更可靠。没有东西可以完全在真空中运行,在复杂的系统中总是有许多因素在起作用。
好消息是,计算机系统实际上并不需要完美。计算机系统甚至在硬件层面采用了错误检测和校正技术。从一开始,我们现在使用的网络协议都有内置的系统来处理错误和故障,因为我们都知道,不管你如何处理这些错误和故障,它们都会发生。
即使在最高级别,比如人们浏览网页并期望加载,也会发生某种类型的故障。网页可能加载缓慢,或者部分网页根本无法加载,或者登录按钮无法点击。这些都是人们已经预料到的事情,只要它们不经常发生或只在特别重要的时刻发生,通常都可以接受。
SLO就是这样。它们是你失败或无法正常运行的频率的目标,同时还能确保你的用户不会感到不安。如果一个网站的访问者有一个页面加载速度非常慢甚至没有加载出来,他们可能会耸耸肩,尝试刷新页面。但是,如果每次访问网站时都会发生这种情况,用户最终会放弃它,并找到另一个适合他们的网站。
你想给你的用户一个好的体验,但是如果你想确保这种好的体验100%地发生,则会以各种方式耗尽资源。SLO可以让你选择一个介于两者之间的目标。
重要的是要重申SLO是目标,而不是任何形式的合同协议。你应该随时根据需要改变或更新你的目标。任何事情都会发生变化,这些变化可能会影响服务的运行方式。这些更改也可能会改变用户的期望值。有时候你需要降低你的SLO,因为曾经那个合理可达的目标已经不复存在;有时你需要提高你的目标,因为用户的需求已经发生变化。这一切都很好,在这些阶段进行的讨论是基于SLO可靠性方法的一些最重要方面。第4章和第14章将探讨如何选择SLO目标以及何时应该更改这些目标的各种策略。
1.2.3 错误预算
在某种程度上,错误预算在可靠性栈中级别最高。这不仅是因为它依赖于栈的SLI和SLO,而且因为它们是最难有效实现和使用的部分。此外,虽然错误预算在向其他人解释服务的可靠性状态时非常有用,但它们有时比你预期的要复杂得多。
在计算错误预算方面有两种截然不同的方法:基于事件的和基于时间的。适合你的方法很大程度上取决于可用数据的保真度、系统的工作方式,甚至个人偏好。在第一种方法中,你考虑好的事件和坏的事件,其目的是计算在一个定义的错误预算时间窗口内,在用户没有感到不满意的情况下,可能会发生多少不良事件。
第二种方法则侧重于“故障时间间隔”的概念(通常称为“故障时间”,即使你的度量分辨率远低于分钟),这为你提供了另一种解释服务当前状态的方法。例如,假设你有一个30天的窗口,你的SLO说你的目标可靠性是99.9%。这意味着在超出错误预算之前的30天内,你可能会有0.1%的故障或坏事件。然而,你也可以将其定义为“我们每个月有43min的故障时间,并达到我们的目标”,因为30天的0.1%大约是43min。不管怎样,你说的都是同一件事,你只是在使用同一理念的不同实现。
错误预算计算以及关于使用哪种方法的决策,可能会变得相当复杂。第5章将详细介绍处理这个问题的策略。
在最基本的层次上,错误预算只是表示一个服务在一段时间内可能出现的故障。它们允许你说“我们这个月还有30min的错误预算”或者“在本月的错误预算用完之前,我们每天可以犯5000多个错误”。然而,错误预算对沟通的作用远不止如此。从根本上说,它们是非常重要的决策工具。虽然在实践中这一方法的工作方式有很多细微差别,但图1-3说明了它们在决策过程中所起的基本作用。
图1-3:关于如何使用错误预算来驱动决策的基本图示
典型的例子是,如果你有剩余的错误预算,就可以随意部署新的更改、发布新的功能、进行实验、执行混沌工程等。但是,如果你超出了错误预算,则应该退一步,集中精力让你的服务更可靠。当然,这个基本的例子就是一个简单的例子。为了让你做出决策,进行正确的讨论是很重要的。我们将在第5章更详细地讨论错误预算在这些讨论中的作用。