作者 | Eugene Retunsky
策划 | 云昭
通过采用整体方法并利用工程原理和实践,我们可以两全其美——速度和可靠性。
当涉及到在线服务时,正常运行时间是至关重要的,但这并不是唯一需要考虑的事情。想象一下,经营一家网上商店——让你的网站99.9%的时间都可用听起来不错,但如果0.1%的停机时间发生在假日购物季呢?这可能意味着失去大笔销售额。如果你的大多数客户只对少数受欢迎的商品感兴趣呢?如果这些页面不可用,那么网站的其他部分是否正常工作也没关系。
有时,“在高峰时刻随时待命”干系到你生意的成败。不仅仅是电子商务——一小部分机场处理着大部分的空中交通,只有极少数名人家喻户晓,每年只有少数卖座电影占据票房主导地位。到处都是相同的分布模式。
为了取得成功,重要的是不仅要保持正常运行时间,还要为重大事件做好准备。一些团队在关键时间之前实施变更冻结,如黄金日、黑色星期五或网络星期一。这种方法是合理的,但它可能是有限的,因为它不允许团队对意外的机会或关键情况做出快速反应。此外,并不是所有的需求都可以预测,也不总是清楚这些高影响事件何时会发生。这就是“重要时的可靠性”的用武之地。我们需要能够适应和快速响应客户需求的变化,而不会被代码冻结期所阻碍,并为不可预见的情况做好准备。
通过将时间视为一种宝贵的资源,并了解不同时刻的相对重要性,组织可以更好地转化客户价值,并相应地调整风险和可用性预算。这种方法使组织能够灵活应对需求变化,而不会错过关键功能或机会。最后,这是关于当运气来临时做好准备。
需要注意的是,一个系统不是静态的,而是不断变化的。系统本身、托管的基础设施和工程组织都会随着时间的推移而变化。这意味着有关系统的知识也会发生变化,这可能会影响可靠性。
除此之外,无论我们如何努力防止事故和停机,事故和停机都是不可避免的。错误将被发送,错误的配置将被部署,并且会发生人为错误。也可能存在相互依赖性,从而导致停机。一个事件很少有单一的原因,通常是多种因素共同作用的结果。解决方案也是如此,当它们涉及到原则和实践的结合,以减轻停机的影响时,这些解决方案是最有效的。
操作系统通常意味着要应对现实世界的压力,如时间、市场和管理需求,以更快地交付。这可能导致走捷径,并可能损害系统的可靠性。用户群和组织的增长和扩展也会带来额外的复杂性,并导致意外或不可预见的行为和故障模式。然而,通过采用整体方法并利用我将在下面介绍的工程原理和实践,我们可以两全其美——速度和可靠性。这不是非此即彼的情况,而是两者之间微妙的平衡。
1、什么是可靠性
可靠性是任何系统的重要组成部分,因为它不仅保证可用性,而且保证正常运行。一个系统可能是可访问的,但如果它不能准确地运行,它就缺乏可靠性。目标是在系统内实现可用性和准确性,这需要控制故障并将其影响降至最低。然而,并非所有故障都具有同等的重要性。例如,阻止结账和付款的问题远比图像加载中的小故障更重要。重要的是要专注于确保重要功能在关键时刻正确工作。
换句话说,我们希望专注于在高峰时段保持可用性和正确运行,为最重要的功能提供服务,无论是流行页面还是流程的关键部分。确保系统在繁忙时期正常工作是很困难的,但重要的是要以深思熟虑和彻底的方式来处理。这包括对系统的技术、操作和组织方面的思考。这种方法的关键部分包括:
设计具有弹性、容错和自我修复能力的系统。
在极端条件下主动测试系统,以识别潜在的弱点并防止倒退。
有效的操作实践:定义托管拓扑、自动扩展、自动化部署/回滚、实施更改管理、监控和事件响应协议。
应对增长、市场需求和工程质量的竞争压力。
培养一种重视协作、知识共享、开放、简单和工艺的文化。它还需要关注结果,以避免犹豫不决,并为客户提供尽可能好的体验。
此外,我们将扩展“重要时的可靠性(Reliability when it matters)”的概念,并为组织提供切实可行的步骤,以确保关键时刻的可用性和功能。我们将讨论关键要素,如设计可靠性系统、主动测试和监控,并深入研究自动化部署和事件响应协议等实际步骤。
2、可靠性度量:优化的重要工具
在优化服务或系统时,首先定义目标并建立监控进度的方法至关重要。您选择的指标应能让您全面了解系统的可靠性,易于理解、共享,并突出需要改进的领域。以下是一些常见的可靠性指标:
- 事件频率:每单位时间内发生的事件数。
- 事件持续时间:事件持续的总时间。
虽然这些指标是一个很好的起点,但它们并没有显示事故对客户的影响。让我们考虑以下图表:
蓝色-每五分钟的请求数,红色-错误,绿色-0..1中的可靠性
假设我们有两个事件,一个在凌晨1点,另一个在下午2点,每个事件都导致大约10%的请求在30分钟内失败。将这些事件视为对可靠性同样有影响,并不能反映它们对客户的真实影响。通过考虑交通量,可靠性指标可以更好地表明高峰交通期间的事件具有更大的影响,值得更高的优先级。
我们的目标是有一个明确的信号,表明高峰交通期间的事故是一个应该解决的主要问题。这种区别有助于确定任务的优先级,并确保资源得到有效利用。例如,它可以防止营销团队为吸引更多访客所做的努力被浪费。此外,跟踪每个发布的事件频率可以帮助改进部署和测试过程,并减少意外问题。最终,这将导致更快的交付和更低的风险。
3、深入挖掘指标
要更深入地了解这些指标并找到需要改进的地方,请尝试跟踪以下内容:
- 检测时间:注意到一个事件需要多长时间。
- 通知时间:通知相关方需要多长时间。
- 修复时间:修复一个事件需要多长时间。
- 事件间隔时间:这可以揭示系统故障的模式或趋势。
- 操作项完成率:完成任务的百分比。
- 行动项目解决时间:实施解决方案所需的时间。
- 高严重事故的百分比:这衡量系统的总体可靠性。
最后,在每周运营期间定期审查这些指标有助于关注进展、识别成功并确定优先级。通过将此作为您文化的常规组成部分,您可以使用这些指标中的数据来推动更好的决策并逐步优化系统。
记住,衡量标准的有用性在于从中采取的行动及其推动进步的能力。这是一个不断完善数据和行动项目的反馈循环,以保持系统的改进。
4、弹性设计
一个没有弹性的系统可能无法顺利处理高峰时间。以下是一些有助于确保系统在各种条件下的可靠性的注意事项:
要做的:
- 为组件故障做好准备:通过划分服务或使用隔离,可以限制爆炸半径并减少故障的影响。
- 实现容错:实现重试、请求对冲和背压等机制将提高系统的可用性和性能。
- 使用速率限制和流量配额:不要仅仅依靠上游依赖关系来保护自己。使用速率限制和流量配额来确保您的系统保持可靠。
- 分类功能: 通过将职能划分为“关键”、“正常”和“尽最大努力”类别来确定职能的优先级。这将有助于在高需求期间不惜一切代价保持基本功能的可用性。
- 实现错误定步和甩负荷:这些机制有助于防止或减轻流量滥用或滥用。
- 持续挑战系统:持续挑战系统并考虑潜在故障,以确定需要改进的领域。
- 恢复计划:实施故障转移机制,并在发生故障时计划恢复。这将有助于减少停机时间,并确保在具有挑战性的条件下提供基本服务。
- 进行战略权衡:在具有挑战性的外部条件下,进行战略权衡并优先考虑基本服务。
不要做的:
- 不要以为调用者会按预期使用您的服务。
- 不要忽视罕见但潜在的失败;规划和设计预防措施。
- 不要忽视硬件故障的可能性。
5、可靠性测试
可靠性测试对于在高需求期间保持系统的可用性和功能性至关重要。为了确保系统的可靠性,重要的是:
- 针对可测试性进行设计,以便可以单独测试每个组件。
- 有足够好的测试覆盖率作为敏捷的先决条件。
- 按重要性校准测试,将重点放在基本功能上,并对次要或实验功能给予一点放松。
- 进行广泛的非功能测试,如负载测试、压力测试、故障注入测试、浸泡测试和模糊/组合测试。
有必要避免以下情况:
- 盲目追求高覆盖率。
- 假设一个数据点可以提供全面的理解。确保结果具有可重复性。
- 测试环境和工具投资不足。
适当的测试不仅可以确保正确性,作为活的文档,防止非功能性的倒退,还可以帮助工程师更深入地理解系统,在试图挑战系统的同时发挥他们的创造力,并最终为所有利益相关者创造更具弹性、更可靠的系统。
记住,如果你不故意对你的系统进行压力测试,你的用户会为你做的。那一刻何时到来,你将无法选择。
6、以可靠性为导向的运维
运维分布式系统就像指挥管弦乐队,这是一门精细的艺术,需要高水平的技能和对细节的关注。许多工程师倾向于低估操作的重要性,或者将其视为软件开发的次要因素。然而,在现实中,操作可能会对系统的可靠性产生重大影响。
就像指挥家的技巧和对管弦乐队的理解对于确保和谐的表演至关重要。例如,云计算提供商通常提供基于开源产品的服务。这不仅仅是关于使用软件,还有你如何使用它。这是云计算提供商业务的重要组成部分。
为了确保可靠性,需要考虑运维的三个关键方面:
- 运行服务:这涉及到托管配置、部署过程和定期维护任务,如安全补丁、备份等。
- 事件预防:实时监控系统以快速检测和解决问题,定期测试系统的性能和可靠性、容量规划等。
- 事件响应:制定明确的事件响应协议,定义团队成员在事件中的角色和责任,以及有效的审查、沟通和后续机制,以解决问题,防止类似事件发生或最大限度地减少其在未来的影响。
事件响应方面尤其重要,因为它可以作为现实核查。毕竟,所有采取的措施都是不够的。这是一个谦逊的时刻,也是一个意识到世界比我们想象的要复杂得多的时刻。我们需要尽可能诚实地找出导致这起事件的所有工程和程序缺陷,并看看我们未来可以做得更好。
为了使事件回顾有效,考虑采用以下做法:
- 假设读者事先不了解您的服务。首先,你写这个回顾是为了分享知识,写得清楚,让别人理解。
- 确定事件的影响。这有助于调整在后续措施中投资所需的工作量。只有相对严重的事件才需要一个深入的过程,不要对每一个不可能产生持久影响的小问题都进行回顾,从而使回顾正常化。
- 不要停留在舒适的答案上。深入挖掘,不必担心个人的自负。目标是改进流程,而不是责怪个人或感到内疚。
- 优先考虑本可以防止或大大降低事件严重程度的行动项目。目标是尽可能少的行动项目,每个项目都有关键的优先级。
就不止步于“舒适的答案”而言,重要的是要确定并解决长期可靠性的根本原因。以下是一些可能导致服务中断的表面级别问题的示例:
- 推送配置时出现的人为错误
- 不可靠的上游依赖性导致无响应。
- 交通高峰导致我们的服务暂时无法使用。
根据这些诊断,很难提出长期提高可靠性的行动项目。另一方面,更深层次的根本原因听起来可能是:
- 我们的系统允许在没有安全检查的情况下将无效配置部署到整套业务。
- 我们的服务没有处理上游的不可用性,并加剧了停机。
- 我们的服务没有保护自己不受过度流量的影响。
解决根本原因可能更具挑战性,但这对于实现长期可靠性至关重要。这只是我们在运营方面应该努力的一个简短概述,但还有更多的东西需要探索和考虑。从事件响应协议到容量规划,有许多细微差别和最佳实践需要注意。
7、系统可靠性中的人为因素
虽然程序和机制在确保系统可靠性方面发挥着至关重要的作用,但最终是人类将其付诸实践。因此,这不仅仅是要拥有正确的工具,还要培养正确的心态,为这些机制注入活力,使其有效运行。以下是有助于(不仅如此)保持可靠性的一些关键品质和习惯:
- 与其他团队和组织合作,以共享知识并朝着共同目标努力。
- 一定程度的谦逊和对新信息的开放态度,以适应和发展系统。
- 专注于简单性和工艺性,以创建可进化和可维护的系统。
- 行动驱动、注重结果的心态,避免停滞不前和犹豫不决。
- 一种类似于儿童的好奇和实验方法,不断寻求了解系统是如何工作的,并找到改进它的方法。
8、总结
确保系统的可靠性是一项全面的工作,包括找出正确的指标,考虑到弹性进行设计,以及实施可靠性测试和操作。通过关注可用性、功能性和满足最重要的需求,组织可以更好地转化客户价值,并相应地调整风险和优先级。
建立和维护一个即使在最恶劣的条件下也能处理的系统,不仅有助于推动业务成功并取悦客户,而且还能给从事该系统的人带来成就感。可靠性是一个持续的过程,需要关注、技能和纪律。通过遵循最佳实践,不断挑战系统,培养有韧性的心态,团队和组织可以创建强大可靠的系统,能够承受任何挑战。
原文链接:https://dzone.com/articles/the-art-of-being-ready-reliability-in-extreme-cond