失败是不可避免的。磁盘会故障。软件错误潜伏着,等待合适的条件来爆发。人会犯错。数据中心建立在不可靠的商用硬件之上。如果您在云环境中运行,那么许多这些因素都在您的控制范围之外。更糟糕的是,失败是不可预测的,并且不会以均匀的概率和频率发生。缺乏均匀的频率增加了系统的不确定性和风险。面对如此不可避免和不可预测的失败,您如何构建一个可靠的服务,以提供用户可以依赖的高可用性水平?
一种朴素的方法可能是尝试通过严格的分析来证明系统的正确性。它可以模拟所有不同类型的故障,并通过模拟或其他理论框架(模拟或分析真实运行环境)来推导出系统的正确运行方式。不幸的是,行业中静态分析和测试的先进水平尚未达到这些能力。4
另一种方法可能是尝试创建详尽的测试套件,以在单独的测试环境中模拟所有故障模式。每个测试套件的目标是维护每个组件的正常运行,以及单个组件发生故障时整个系统的正常运行。大多数软件系统以一种或另一种形式使用这种方法,结合单元测试和集成测试。更高级的用法包括测量测试的覆盖面以指示完整性。
虽然这种方法确实提高了系统质量,并且可以防止大量的故障,但它不足以在
本文提倡的另一种方法是在系统中诱导故障,以实证地证明韧性并验证预期行为。鉴于系统在设计时就考虑了对故障的韧性,诱导这些
在进一步讨论之前,让我们讨论一下韧性的含义以及如何提高韧性。韧性是系统的一种属性,使其能够以不会导致整个系统崩溃的方式处理故障。它可能涉及在发生故障时最大限度地减少爆炸半径,或者改变用户体验以绕过故障组件。例如,如果电影推荐服务失败,则可以向用户呈现非个性化的热门电影列表。一个复杂的系统不断经历不同程度的故障。韧性是它如何从当前和未来的故障中恢复或被隔离。7
有两种方法可以提高系统的韧性
• 使用冗余和容错构建应用程序。 在
• 通过定期诱导故障来减少不确定性。 增加故障的频率会降低其不确定性以及不适当或意外响应的可能性。可以在观察应用程序的同时诱导每个独特的故障。对于每个对诱导故障的不良响应,可以应用第一种方法来防止其再次发生。虽然在实践中诱导每种可能的故障是不可行的,但枚举可能的故障并对其进行优先级排序的练习有助于理解可容忍的运行条件,并在故障超出这些范围时对其进行分类。
第一项在其他文献中得到了很好的涵盖。本文的其余部分将侧重于第二项。
一旦您接受了定期诱导故障的想法,关于如何进行,还有一些选择。一种选择是 GameDays1,这是一系列计划好的演练,其中手动引入或模拟故障以反映
但是,如果您想要一个更具可扩展性和
实现这一目标的一种方法是设计故障在生产环境中发生。这就是 Netflix “猴子”(实际上是自主代理,但猴子激发了想象力)的想法的由来,目的是制造混乱并诱导故障。后来,猴子们被组合在一起,并被标记为猿人军团。5 下文描述了每个与
虚拟实例的故障是在典型的公有云环境中遇到的最常见的故障类型。它可能是由托管机架中的电源中断、磁盘故障或网络分区造成的,网络分区会切断访问。无论原因是什么,结果都是一样的:实例变得不可用。诱导此类故障有助于确保服务不依赖于任何
为了解决这一需求,Netflix 创建了它的第一只猴子:混沌猴,它随机终止生产
混沌猴首先查看服务注册表以查找正在运行的所有服务。在 Netflix 的案例中,这是通过 Asgard6 和 Edda2 的组合完成的。每个服务都可以覆盖默认的混沌猴配置,以更改终止概率或完全退出。每小时,混沌猴都会醒来,掷骰子,并使用 AWS(亚马逊网络服务)API 终止受影响的实例。
混沌猴可以选择在终止实例时向服务所有者发送
有了混沌猴,系统可以应对单个实例故障,但如果整个数据中心变得不可用怎么办?如果整个亚马逊 AZ(可用区)离线,会对用户产生什么影响?为了回答这个问题并确保此类事件对客户的影响最小,Netflix 创建了混沌猩猩。
混沌猩猩会导致整个 AZ 发生故障。它模拟两种故障模式
• 网络分区。 该区域中的实例仍在运行,并且可以相互通信,但无法与该区域外的任何服务通信,并且该区域外的任何其他服务都无法访问它们。
• 完全区域故障。 该区域中的所有实例都被终止。
混沌猩猩会造成巨大的破坏,并且需要一个复杂的控制系统来重新平衡负载。对于 Netflix 来说,该系统仍在开发中,因此,混沌猩猩是手动运行的,类似于前面提到的 GameDay 演练。随着每次连续运行,混沌猩猩在执行
一个区域由多个数据中心(可用区)组成,这些数据中心旨在彼此隔离。一个健壮的部署架构通过使用多个 AZ 来实现 AZ 冗余。在实践中,区域范围的故障确实会发生,这使得
一旦混沌猴运行起来,单个实例故障不再有任何影响,就会出现一类新的故障。处理实例故障相对容易:只需终止坏的实例,让新的健康实例取代它们的位置即可。检测实例何时变得不健康但仍在工作更加困难,并且对此故障模式具有韧性也更加困难。
错误率可能会升高,但服务可能会偶尔返回成功。服务可能会回复成功的响应,但延迟可能会增加,导致超时。
Netflix 需要的是一种诱导故障的方法,该方法模拟部分健康的实例。这就是延迟猴的起源,它在 RESTful
猿人军团的其余部分,包括清洁工猴,负责维护和其他与可用性没有直接关系的任务。完整的参考资料可在 http://techblog.netflix.
虽然猿人军团是一个新颖的概念,可能需要视角上的转变,但它的实现并不像最初看起来那么困难。了解 Netflix 的经历对于其他有兴趣遵循这条道路的人来说具有启发意义。
Netflix 以其在快速追求创新和高可用性方面的胆识而闻名,但并非到了麻木不仁的地步。它小心翼翼地避免这些故障诱导演练对客户产生任何明显的影响。为了最大限度地降低风险,Netflix 在引入猴子时会采取以下步骤
1. 在测试环境中,工程师使用新的猴子观察用户体验。目标是对客户产生可忽略不计或零影响。如果工程师看到任何不利结果,那么他们会进行必要的代码更改以防止再次发生。重复此步骤多次,直到未观察到不利的用户体验。
2. 一旦在测试环境中未观察到不利结果,新的猴子就会在生产环境中启用。最初,新的猴子在
3. 在许多服务选择加入后,新的猴子升级到
4.
如果不强调监控的重要作用,那么关于韧性的讨论就不完整。这里的监控意味着观察系统及其组件的外部和内部状态,并可选择性地发出警报的能力。在故障诱导和韧性的背景下,监控对于两个原因很重要
• 在真正的、非模拟的、影响客户的事件期间,重要的是尽快稳定系统并消除对客户的影响。必须在此期间停止任何导致额外故障的自动化。不这样做可能会导致混沌猴、延迟猴和其他猿人进一步削弱已经不健康的系统,从而导致更大的不利
• 构建韧性系统并非一蹴而就;这是一个持续的过程,涉及发现弱点并在迭代学习周期中处理它们。深入了解系统是理解系统如何运行以及如何失败的关键。如果没有指标和对系统及其组件运行情况的深入了解,很少有
在
对故障的韧性是一个崇高的目标。它使系统能够生存并承受故障。然而,还有一个更高的目标要努力实现:使系统每次故障都变得更强大更好。用 Nassim Taleb 的话来说,它可以变得反脆弱——从每次连续的压力源、干扰和故障中变得更强大。8
Netflix 已采取以下步骤来创建更具反脆弱性的系统和组织
1. 每位工程师都是服务的运维人员。 这有时在玩笑中被称为“无运维”,尽管它实际上更像是“分布式运维”。将开发和运维分开会造成责任划分,这可能会导致许多挑战,包括网络外部性和错位的激励机制。网络外部性是由运维人员感受到开发人员引入的问题的痛苦引起的。错位的激励机制是运维人员想要稳定而开发人员想要速度的结果。DevOps 运动是为了响应这种分歧而发起的。与其将开发和运维分开,不如让开发人员运维自己的服务。他们将代码部署到生产环境,如果代码的任何部分崩溃并影响客户,他们就是半夜被叫醒的人。通过结合开发和运维,每位工程师都可以通过更改服务以使其对未来故障更具韧性和容忍度来响应故障。
2. 每次故障都是一个学习机会,产生以下问题: “如何更快地检测到故障?” “如何使系统对这种类型的故障更具韧性?” “如何定期诱导这种故障?” 结果是,每次故障都会使系统变得更加健壮和具有韧性,类似于战士在每场战斗中获得的经验,使他在下一次战斗中变得更强大和更凶猛。系统失败的次数和方式越多,系统就变得越好。
3. 培养无责文化。 作为一个组织,Netflix 优化创新和速度,并且它接受有时会发生错误,并将每个错误都用作学习的机会。在 Netflix 经常听到的一句话是:“如果我们没有犯任何错误,那就意味着我们行动不够快。” 除非重复犯同样的错误,否则错误不是坏事。结果是人们不太担心犯错,并且可以将事后分析构建为有效的学习机会(参见步骤 2)。
故障发生的频率越高,系统和组织就越能准备好以透明和可预测的方式处理故障。诱导故障是确保系统和组织韧性的最佳方法。目标是最大化可用性,将服务用户与故障隔离开来,并提供一致且可用的用户体验。可以通过增加故障的频率和多样性,并不断改进系统以更好地处理每次新发现的故障来提高韧性,从而提高反脆弱性。专注于学习和培养无责文化是创建系统中适当反馈的关键组织要素。
1. Robbins, J., Krishnan, K., Allspaw, J., Limoncelli, T. 2012. 韧性工程:学习拥抱失败。Communications of the 55(11): 40-47; http://dx.doi.org/10.1145/2366316.2366331。
2. Bennett, C. 2012. Edda - 了解您的云部署的故事。Netflix 技术博客; http://techblog.netflix.com/2012/11/edda-learn-stories-of-your-cloud.html。
3. Bennett, C., Tseitlin, A. 2012. 混沌猴发布到野外。Netflix 技术博客; http://techblog.netflix.com/2012/07/chaos-monkey-released-into-wild.html。
4. Chandra, T. D., Griesemer, R., Redstone, J. 2007. Paxos made live: an engineering perspective. 在 Proceedings of the 26th Annual Symposium on Principles of Distributed Computing: 398-407; http://labs.google.com/papers/paxos_made_live.pdf。
5. Izrailevsky, Y., Tseitlin, A. 2011. Netflix 猿人军团。Netflix 技术博客; http://techblog.netflix.com/2011/07/netflix-simian-army.html。
6. Sondow, J. 2012. Asgard:基于 Web 的云管理和部署。Netflix 技术博客; http://techblog.netflix.com/2012/06/asgard-web-based-cloud-management-and.html。
7. Strigini, L. 2009. 容错和韧性:含义、度量和评估。英国伦敦:伦敦城市大学软件可靠性中心; http://www.csr.city.ac.uk/projects/amber/resilienceFTmeasurementv06.pdf。
8. Taleb, N. 2012. 反脆弱:从无序中获益的事物。Random House。
喜欢或讨厌?请告诉我们 [email protected]
Ariel Tseitlin 是 Netflix 的云解决方案总监,他在那里管理 Netflix 云,并负责云工具、监控、性能和可扩展性以及云运维和可靠性工程。他还对韧性和高可用性分布式系统感兴趣。在加入 Netflix 之前,他最近担任 Sungevity 的技术和产品副总裁,再之前是 CTOWorks 的创始人兼首席执行官。
© 2013
最初发表于 Queue 第 11 卷,第 6 期—
在 数字图书馆 中评论本文
Sanjay Sha - 企业应用程序的可靠性
企业可靠性是一门学科,它确保应用程序以一致、可预测且经济高效的方式交付所需的业务功能,而不会损害可用性、性能和可维护性等核心方面。本文介绍了一组企业可以应用的核心原则和工程方法,以帮助他们驾驭复杂的企业可靠性环境,并交付高度可靠且经济高效的应用程序。
Robert Guo - MongoDB 的 JavaScript Fuzzer
随着 MongoDB 随着时间的推移变得更加功能丰富和复杂,开发更复杂的方法来查找错误的需求也在增长。三年前,MongDB 将其自制的 JavaScript fuzzer 添加到其工具包中,它现在是我们最多产的错误查找工具,负责在两个发布周期中检测到近 200 个错误。这些错误涵盖了从分片到存储引擎的各种 MongoDB 组件,症状从死锁到数据不一致不等。fuzzer 作为 CI(持续集成)系统的一部分运行,它经常捕获新提交代码中的错误。
Robert V. Binder, Bruno Legeard, Anne Kramer - 基于模型的测试:它的现状如何?
您可能听说过 MBT(基于模型的测试),但像许多没有使用过 MBT 的软件工程专业人员一样,您可能对其他人使用这种测试设计方法的经验感到好奇。从 2014 年 6 月中旬到 2014 年 8 月初,我们进行了一项调查,以了解 MBT 用户如何看待其效率和有效性。2014 年 MBT 用户调查是 2012 年类似调查的后续调查,向所有评估或使用过任何 MBT 方法的人开放。它的 32 个问题包括 2013 年高级自动化测试用户会议上分发的一些调查中的问题。一些问题侧重于 MBT 的效率和有效性,提供了管理者最感兴趣的数据。
Terry Coatta, Michael Donat, Jafar Husain - EA 的自动化 QA 测试:事件驱动
对于数百万游戏爱好者来说,在 Electronic Arts 担任 QA(质量保证)测试员的职位似乎是一个梦想的工作。但从公司的角度来看,与 QA 相关的开销可能看起来非常可怕,尤其是在大型多人游戏时代。