假期购物季即将到来,一家为全国最大的在线零售业务之一处理交易的数据中心却出了大问题。一些系统发生故障,但无人知晓原因。工程师团队昼夜不停地工作了三天试图恢复,压力水平已达峰值。
好消息是,这并非真正的灾难——尽管本可能如此。相反,这是一次旨在教会公司如何适应不可避免事件的演练:系统故障。事物会崩溃;灾难会发生;失败是真实存在的。尽管没有人——或许最不希望如此的是软件开发人员和系统工程师——愿意相信他们无法阻止失败,但为失败做好准备的关键首先是接受它。
许多运营部门正在转向弹性工程,并非希望变得对失败免疫,而是为了更好地适应失败发生时的情况。弹性工程在航空和医疗保健等高风险行业中是一个熟悉的概念,现在也正被大型 Web 运营部门采用。
在 2000 年代初期,亚马逊创建了 GameDay 计划,旨在通过有目的地定期向关键系统注入重大故障来发现缺陷和微妙的依赖关系,从而提高弹性。基本上,GameDay 演练是在为应对灾难性事件做准备的过程中,测试公司的系统、软件和人员。GameDay 概念的广泛接受经历了几年时间,但许多公司现在看到了它的价值,并已开始采用自己的版本。本次讨论将探讨其中一些经验。
参与者包括 Jesse Robbins,他是亚马逊 GameDay 的架构师,在亚马逊他被正式称为“灾难大师”。Robbins 在开发 GameDay 时借鉴了他作为消防员的培训,遵循了类似的事件响应原则。他于 2006 年离开亚马逊,创立了 Velocity Web 性能与运营大会,这是 O'Reilly 举办的面向构建互联网规模系统的人员的年度会议。2008 年,他创立了 Opscode,该公司开发了 Chef,这是一个流行的基础设施自动化框架。John Allspaw 也在稍小规模上运行 GameDay 运营,他是 Etsy 的技术运营高级副总裁。Allspaw 在加入 Flickr 担任工程经理之前,曾在 Salon.com 和 Friendster 工作过,于 2005 年加入 Flickr。他于 2010 年加入 Etsy。他还最近从 Robbins 手中接任 Velocity 大会主席。
谷歌的 GameDay 等效项目由 Kripa Krishnan 负责运营,她几乎从该项目启动之初的六年前就参与其中。她还参与其他基础设施项目,其中大多数项目都专注于保护用户及其数据。
主持本次讨论的是谷歌的同事 Tom Limoncelli,他是一位站点可靠性工程师。他在系统管理员圈子里广为人知,最初在贝尔实验室工作,并撰写了四本书,最著名的是《系统管理员的时间管理》和《系统和网络管理实践》。
TOM LIMONCELLI Jesse,您可能比任何人都参与过更多的 GameDay 演练。您从中获得的最重要的教训是什么?
JESSE ROBBINS 最重要的是,我了解到构建弹性系统的关键是接受失败会发生。这是无法回避的。这适用于软件学科,也适用于系统管理和架构学科。它也适用于人员管理。
只有在您接受失败不可避免的现实之后,您才能开始迈向真正弹性系统的旅程。每个弹性计划的核心——无论您在谷歌、Facebook、Etsy、Flickr、雅虎还是亚马逊找到的——都是这样一种理解,即当您着手构建互联网规模的系统时,您能期望的最好结果是在完全不可靠的组件之上构建一个可靠的软件平台。这会将您置于一个复杂故障既不可避免又无法预测的环境中。
KRIPA KRISHNAN 我们也学到了一些东西。其中最重要的教训是,未经测试的灾难恢复计划根本不能算作计划。我们现在也知道,如果做某事很困难,重复将有助于使它变得更容易。在谷歌的规模下,即使只有百分之一的失败几率,也意味着失败很可能发生多次。我们的计划是先发制人地触发失败,观察它,修复它,然后重复,直到该问题不再是问题。在我们最近的 GameDay 演练中,我们重新测试了一些在两到三年前导致严重故障的事情,并高兴地发现它们现在可以毫不费力地解决。
我们还了解到,真正的成功并非来自每年只运行一次 GameDay 测试,而是来自让团队全年都在内部测试他们的服务。也就是说,GameDay 为我们提供了一个测试一些不太常用的环节的机会。例如,我们设计的测试需要来自多个通常不会一起工作的团队的工程师相互互动。这样,如果真的发生大规模灾难,这些人将已经建立起牢固的工作关系。
另一个重点是,人们在 GameDay 上被要求执行的任何功能都与他们在其他任何一天所做的事情没有显着差异。这样,一旦真的发生故障,就不会有任何不寻常的事情需要记住或恐慌。
TL 说到恐慌,从软件工程师或系统管理员的角度来看,这些演练是什么样的?他们在这些演练中实际经历了什么?
JR 我在亚马逊设计的计划始于一系列公司范围内的简报,告知所有人我们即将进行一定规模的演练——例如,类似于全面数据中心摧毁的演练。他们不知道哪个数据中心将被离线,也不知道它将在何时发生,但他们通常有几个月的时间来确保他们的系统能够承受突然失去大量容量。期望是他们将利用这段时间来确保他们已经消除了他们可以找到的所有单点故障。
一旦事件实际发生,人们通常会收到通知,作为我们标准事件管理流程的一部分,通常包括一些特定于他们站点的消息。例如,我们可能会告诉他们某些服务器不再响应,或者他们的服务已经损失了一些容量。希望他们自己的标准监控工具已经发现了所有这些,但也有一些情况是 GameDay 演练最终导致了这些监控能力的丧失。这并非您希望看到的,但这仍然是这些演练真正擅长暴露的经典缺陷之一。
有时您还会暴露我们称之为“潜在缺陷”的东西——仅由于您触发的故障而出现的问题。例如,您可能会发现,作为您精心策划的故障的一部分,对于恢复过程至关重要的某些监控或管理系统最终会被关闭。您会发现一些您不知道的单点故障。但是,正如 Kripa 所说,随着您以越来越强烈和复杂的方式进行越来越多的这些演练,它确实开始变得只是做生意的常规、普通的一部分。
TL 那么作为一名工程师,当我收到页面通知我我们的一个数据中心刚刚宕机时,我可能正坐在我的办公桌前。这会是关于完全虚构的事情的页面,还是我们正在谈论有人实际拔掉了电缆的情况,可以这么说?
JR 在我设计的演练中,我们使用了真实的故障。我们会真正地关闭一个设施——不经通知——然后让系统自然地发生故障,并允许人们遵循他们的流程,无论这些流程将他们引向何处。在其中一次演练中,我们实际上借鉴了我的消防服务背景,构思了一场模拟火灾。我按分钟写出了时间安排,根据我们预计在全面火灾响应中会发生某些事情的时间。然后,冒充一些设施人员,我们打电话给运营人员,向他们更新正在发生的事情。
我的观点是,您希望使这些演练尽可能真实,以便暴露那些特殊的系统和后门盒子,一些系统管理员为了应对紧急情况一直在保留这些系统和盒子。并非这些演练中的所有内容都可以模拟,一旦您开始关闭机器或破坏核心软件组件,浮出水面的问题是真实的。尽管如此,重要的是要明确表示,演练核心的“灾难”仅仅是模拟的,这样外围的人就不会惊慌失措。否则,演练过程中发生的事情应该感觉尽可能真实。
JOHN ALLSPAW 是的,而且演练也应该让人感到有点不舒服。事实是,事情常常以我们无法想象的方式崩溃。在应对这些意外的过程中,您当然有机会从错误中吸取教训。最终,您还有机会获得信心,相信您构建的系统和围绕它建立的组织实际上相当有弹性。
TL 在谷歌,这是如何运作的,Kripa?
KK 我们通常会提前三到四个月通知人们,告诉他们事件将在某个特定的一周或一个月内发生。GameDay 事件本身通常是一个昼夜不停、持续 72 到 96 小时的演练。即使人们不知道确切的时间,他们也知道即将到来一段时间,这段时间内将会有很多中断,并且他们将被期望像应对真实事件一样应对每一次中断。
我们精心策划的中断范围,一方面包括技术故障,例如关闭整个数据中心或故意损坏我们后端的数据,另一方面包括测试人为因素的演练——例如,创建一个整个团队在 72 小时内与外界失联的情况,迫使其他团队绕过他们工作,以模拟地震后可能发生的情况。涉及不太严重问题的测试可能只会持续几个小时,而更大规模的测试往往会持续几天。其想法始终是尽可能多地了解公司在压力下以及在容量减少的情况下,在较长时间内的表现。
为了让您对规模有一个概念,我们通常有数百名工程师在一次演练期间昼夜不停地工作。我们通常有一组工程师负责响应测试,另一组工程师充当“监考员”监控测试。监考员密切关注 IRC(互联网中继聊天)频道上来回传递的通信。我们还配备了“作战室”,以确保事情不会失控到最终使情况变得更糟或影响生产环境。
粗略地说,在测试的前 24 小时内,一切都与初始响应有关。大问题通常在那时浮出水面。在 24 到 48 小时之间,会进行大量的例行团队间测试。独立的工程团队为其他地点的同行编写测试,他们最终会进行大量的双向测试。然后,到 72 小时标记时,疲惫的迹象真的开始显现。事实证明,疲惫和其他人为因素是我们测试的重要组成部分。那是因为,在真正的紧急情况下,您可能无法选择在轮班结束时交接工作。
您早些时候问过发送出去的页面是虚构的还是真实的。我们实际上确实会真实地呼叫人们,但我们也尽量明确表示页面与 GameDay 测试有关。我们最不想看到的是让测试的优先级高于真正的生产问题。尽管如此,我们也遇到过我们了解 Jesse 所说的“潜在缺陷”的情况,例如当我们发现寻呼基础设施位于我们关闭的设施中时,这最终导致了相当严重的混乱。
TL 我认为每个人都会经历这种情况。当您学到的第一件事是您的响应框架的某些关键部分在测试范围内时,您就知道您正在进行一次成功的演练。
KK 是的,但只有当您稍后重复测试时,您能够确保一切正常工作,测试才真正成功。在这种特殊情况下,有问题的测试导致大量页面在基础设施中排队,但没有一个页面发送到正确的人员。然后,当我们最终设法撤消测试时,许多寻呼机收到了数千页信息——但无法分辨哪些是真实的,哪些是与 GameDay 相关的。所以您知道这个问题得到了解决!
***
在一些 Web 规模的公司中引入 GameDay 场景,引发了一场艰难的文化转变,从坚定地相信系统永远不应该失败——如果失败了,就专注于责怪谁——到实际迫使系统失败。与其花费资源构建不会失败的系统,重点已开始转向如何在系统确实失败时迅速且专业地处理系统——因为它们终将失败。
失败可能很难推销,但当转变者看到他们可以从 GameDay 演练中学到多少东西时,他们可能会逐渐被争取过来。运行此类演练的大部分价值来自于改变设计和构建系统的工程师的集体心态。看着他们的系统失败并看到由此产生的后果,对他们来说并不容易。然而,随着时间的推移,他们开始对他们所依赖的系统和实践实际上相当有弹性充满信心。
信奉 GameDay 理念的公司也希望营造一种更公正的文化——在这种文化中,人们可以被追究责任,而不会因失败而被责备或惩罚。
TL 您已经成功地在精心策划灾难的业务中站稳了脚跟,但传统上,管理层认为任何和所有中断都是完全不可接受的。这是否表明一场重大的文化转变?
KK 在我们灾难恢复测试计划的最初几年里,我们确实经历了一场重大的文化转变。然而,真正对我们有利的是,我们有一位坚定的赞助人——我们的副总裁 Ben Treynor——他坚信,确保某件事按预期工作的唯一方法就是测试它。但即使有如此强大的支持,我们仍然遇到了一些重大阻力。特别是一些非工程部门只看到了将要涉及的风险和投资,一些运营团队只是看不到 GameDay 式测试相对于他们已经进行的持续测试计划的优势。事实上,一个组织的合作意愿的最重要预测因素,被证明是该组织中的人员如何处理先前的故障。如果早期的中断导致了工程调查,而这些调查没有将责任归咎于个人,而是仅仅寻找根本原因,那么该组织几乎总是渴望参与。另一方面,如果早期的中断导致了对罪魁祸首的追捕,那么该组织通常会被证明更不情愿。
然而,今天,GameDay 已被全面接受。我们最近的演练涉及的编写测试的团队数量是五年前的 20 倍,参与者来自技术和业务部门。现在,当我们发现有东西坏了时,没有人感到羞愧。他们只是接受了解问题是一个机会,可以回去修复它。也就是说,现在每个人似乎都明白了,演练的全部意义在于发现问题,以便可以主动实施补救措施或纠正措施。
JR 早在 2003/2004 年,当跨不可靠硬件的横向扩展概念尚未完全形成时,我在亚马逊的经历略有不同——事实上,我们几乎处于最前沿,并且在摸索前进。然而,我们确实认识到,随着我们的站点规模和数量的增长,我们的故障规模和复杂性也在增长。那时我们才意识到,我们可能只有两种方法可以采取:一种是花费尽可能多的钱来使事情更可靠;另一种是,作为一个组织,我们可以选择接受失败会发生的想法。
我很早就获得了高层管理人员的大力支持,因为很明显,我们无法仅仅通过砸钱来解决这个挑战。因此,我们的执行团队立即接受了这样一种观念,即以受控方式触发故障代表着一个机会,让我们能够以更低的成本和更小的干扰来学习一些真正重要的重大教训,而不是仅仅等待问题自行浮出水面。
这成为了运行 GameDay 类型演练的根本基础。也就是说,您无法选择是否会发生故障——无论如何它们都会发生——但在许多情况下,您可以选择何时学习教训。关键是,您真的希望能够在您自己设定的条件下和您选择的时间暴露系统中的缺陷,并且除了触发故障之外,没有其他方法可以找到其中一些问题。
一旦一个组织接受了这种想法,文化往往会很快改变。经历过这个过程的人,尽管可能很困难,但会发现一些有价值的东西,他们中的许多人很快就会成为有力的倡导者。通常不需要很长时间,您就会拥有相当数量的人接受失败会发生,因此坦率地说,他们非常愿意享受破坏东西的乐趣,以便暴露他们知道潜伏在那里的问题。由此产生了一种新的运营文化,但这是一种只能通过一系列演练来建立的文化。
您不能只做一次这些演练,然后就结束了。这是我们从消防服务中吸取的一个重要教训,即人们理解您必须不断地进行训练和演练,才能培养只能随着时间推移才能获得的运营能力。
TL 我不得不指出,当您提到亚马逊的高管们如何迅速接受失败不可避免的观念时,您说了一些非常了不起的话。传统上,高管们被教导,每当发生重大系统故障时,他们应该做的第一件事就是解雇一些人,只是为了向所有人表明他们控制着局势。
JR 我们在亚马逊可能有一个特殊的优势,因为该组织的大部分已经拥有围绕履行中心进行流程优化的经验。基本上,我们已经有了一种工厂运营的心态。
在那段时间左右,我们也发生了一些重大中断,这也起到了帮助作用。因此,人们特别开放和乐于接受做一些不同的事情。在一段时间内没有发生中断的公司中,推销 GameDay 概念可能会有点困难,因为,你知道,自满情绪会滋生。我总是向那些尚未接受拥抱失败的智慧的公司的员工建议,他们应该密切关注任何出现的故障,以及任何其他可能为他们提供论据的理由,以争取进行小型 GameDay 实验的问题。当然,如果实验被证明是成功的,他们应该大力宣传它,指出他们以受控方式设法解决的问题,而不是仅仅等待灾难降临。
JA 您刚才所说的话中,对于任何旨在具有弹性的组织——特别是那些依赖复杂系统的组织——都有一些教训。我所说的弹性,是指在意外干扰之前、期间和之后维持运营的能力——这种干扰超出了设计者预期的范围。
弹性工程领域的先驱 Erik Hollnagel 指出,弹性的四个基石是:(1)知道期望什么(预期);(2)知道要寻找什么(监控);(3)知道该做什么(如何响应);以及(4)知道刚刚发生了什么(学习)。最后一个是事后分析等发挥作用的地方。
Hollnagel 阐述的观点与传统观点略有不同,传统观点认为,失误和中断是某些个人犯下的错误造成的。然而,当您谈论复杂的产品时,缺陷很可能实际上源于整个设计过程中的某些失败,或沿途许多不同产品开发步骤中的某个环节出了问题。也就是说,稍后浮出水面的任何问题的责任实际上应该由集体承担。因此,当所有的责任最终都归咎于个人——很可能是工程师——时,嗯,这简直是荒谬的还原论。这就像说,“这是那个人。他犯了错误,一切都因此而崩溃了。那么我们这里的问题是什么?他是我们的问题。” 这只不过是后见之明偏见的经典例证。
当然,诀窍是让整个组织的人开始通过思考可能出错的事情来锻炼他们的预期能力。您已经在当前的持续部署热潮中看到了这方面的一个方面,因为它专注于如何在更换故障组件进行维修或更换时保持系统正常运行。如果您网站的某个部分坏了,它不应该使整个网站崩溃,对吗?他们不会仅仅因为布鲁克林大桥的一条车道坏了就关闭整座桥。
TL 这涵盖了预期方面。那么弹性的其他基石呢?
JA 最重要的方面之一——也是受到关注太少的方面——是从失败中学习。传统的反应是:某人犯了一个错误...站点宕机...开会...解雇那个人。他一定是粗心大意或疏忽大意,或者甚至可能故意违反了程序。
但我愿意相信,我们的专业文化将逐渐接受在追究人们责任的同时不一定责怪他们的智慧。医疗行业和航空业都从这种态度中受益。除了基本公平的显而易见的问题之外,相信“人为错误”是某个问题的唯一根本原因纯粹是愚蠢的。首先,当您处理像 Web 基础设施这样复杂且固有缺陷的东西时,拥有唯一根本原因的概念本身就很可笑。然后将问题归咎于解雇某人就可以解决,这意味着您真的什么也没学到——而且这肯定无助于您在未来变得更具弹性。
您可以从失败中学到有用的东西的唯一方法是尽可能多地了解导致中断的行为——这意味着找出为什么在当时采取这些特定步骤似乎是合理的。有一些人为因素测试可以对此有所帮助。我们在 Etsy 使用的一种称为替代测试,它在弄清楚为什么有人决定运行最终导致站点宕机的命令时非常方便。我们会找另一位没有参与问题情况的工程师,我们会向他介绍当时的背景以及操作员当时知道的所有细节。然后我们会问那位工程师,“在这种情况下,您会怎么做?” 几乎每一次,他都会告诉我们他会运行完全相同的命令。
因此,问题不是由于缺乏培训、缺乏智力或任何其他个人缺陷造成的。解决方案不仅仅是解雇那个人。事实上,您想留住那个人,并深入探究导致错误的原因。找出为什么他认为他所做的事情是合理的。
我已经多次公开宣布,我永远不会因为有人导致我负责的站点宕机而解雇任何人。我认为很多其他工程领导者不愿意走那么远。事实上,我认为这让我自己组织中的几个人感到非常紧张。
JR 是的,但在许多情况下,您只能从这些错误中学习。
JA 另一方面,有些人认为弹性工程不仅是着眼于未来并试图预测失败,而且还是解构场景,然后再将碎片重新组合在一起,以更好地理解我们过去是如何响应的,以便我们可以思考我们将来如何才能更好地响应。这只是另一种增强我们预期能力的方式。
每当您这样做时,真正令人震惊的事情是考虑您的站点没有失败的所有次数,即使它可能应该失败。除了认真研究为什么您最终遭受了某些特定失败之外,您可能还想反过来问问自己,为什么您没有一直发生故障。
***
GameDay 演练一开始会以容易想象的方式(事实上,通常是以脚本化的方式)破坏事物,但随后事情往往会以一些相当重大和意外的方式偏离脚本。这增加了一个人们必须学会管理的复杂性级别。这些事情为什么会发生,应该如何处理?从 GameDay 演练中收集的信息量可能非常惊人。然后,重要的是要找到处理所有这些信息并将其分发给适当人员的方法,以便在需要时可以使用它。
人为因素也是这种规模的演练中的一个复杂因素。GameDay 可能会持续几天,因此让参与者保持专注可能是一个挑战。您不希望人们变得自满,因此在合理范围内保持压力非常重要。然而,人们在压力大的情况下会犯错误,因此您必须通过在适当的时间间隔轮换人员来补偿疲惫因素。通常,人们不愿意放弃,直到他们解决了问题,尽管此时他们的决策能力可能已经下降。
TL 你们都说过,发现潜在缺陷是触发故障的主要动机之一。有没有什么时候您可以宣布胜利?
KK 实际上没有。原因之一是,对于我们这种规模的组织来说,系统在不断发展,随着新层的增加,仅仅清点所有这些服务就需要付出相当大的努力。随着新功能的开发,复杂性被引入。每当收购需要您合并新的代码库时,就会引入更多的复杂性——当然,这只会使预测哪里可能发生故障变得更加困难。越来越难看清我们的依赖关系在哪里,以及什么可能导致级联故障。找到这些潜在缺陷的唯一方法是运行我们可以触发实际故障的演练。
最好用几个例子来说明这一点。我们遇到过这样的情况:我们关闭了圣保罗的网络,却发现这样做破坏了我们在墨西哥的链接。从表面上看,这似乎完全是异想天开,但当您深入挖掘时,您最终会发现一些以前没有人知道的依赖关系。如果我们没有导致该网络发生故障,我们至今仍不会知道这一点。
我们还遇到过一次这样的情况:我们关闭了一个数据中心,却发现即使在我们尝试重启它们时,那里的大部分机器也不会重新上线。整整一夜一天之后,我们才弄清楚我们已经用完了 DHCP(动态主机配置协议)租约。测试往往也会浮现出像这样愚蠢的东西,但即使是愚蠢的东西也可能产生可怕的后果。
JR 大部分情况下,我们都在讨论一类故障,这类故障通常在你经历一次宕机后才会了解,但我们也看到,在从宕机中恢复的过程中,问题和故障也会不断涌现。自从离开亚马逊以来,我帮助过许多其他组织,并遇到了许多与规模和复杂性相关的恢复问题。随着组织的发展,他们用于配置管理的工具通常跟不上步伐。他们发现自己身处需要将代码部署到 1,000 台新服务器的情况,但这却超出了他们软件部署系统的容量范围。
TL 在一次这样的演练过程中,你们是如何处理所有学到的东西的?
KK 在测试之前、期间和之后,我们都会反复向人们强调,他们应该就发现的每一处故障提交错误报告。这既适用于人员流程,也适用于代码中的错误。我们这些负责管理演练的人员也会提交我们自己的一套错误报告。我们有一个轮换团队,大约有 50 人分布在世界各地的作战室中——主要是志愿者——每个人都专注于运营的不同部分。当我们发现有故障的地方时,我们都会不断地在便利贴和白板上记笔记。
演练结束后,我们会花几周时间将所有信息整理成一份报告,并整理出一份待办修复的清单。这可能是这项工作中最难的部分。数百个服务会产生数千个问题。这些问题会被处理,更重要的是,会被优先排序。复杂的公司级问题需要得到多个组织的认同,而特定于服务的错误只需要针对每个团队提交即可。实际上,这就是全部流程。一旦将正确的信息呈现在正确的人面前,我们就可以——只需付出微不足道的努力——就能关闭每次 GameDay 演练中提出的 80% 到 85% 的问题。
无论这些变更最终如何实现,最重要的一点是组织要意识到持续测试其系统以及不同团队之间、以及所有底层技术之间的集成点是多么重要。这对于互联网公司尤其重要,因为他们依赖的基础设施和软件都在不断变化。如果不通过测试,就无法知道你变更后的系统能够承受什么,而这意味着要通过 GameDay 式的演练来触发实际的故障。
JA 记住 Web 工程领域只有大约 11 年的历史,这对我们所有人也很有帮助。与此同时,一些工程领域在构建和维护复杂系统方面拥有数十年的经验,因此,可以考虑借鉴其他一些领域,看看我们可以在设计原则和最佳实践方面学到什么,并将其应用于我们自己的目的。GameDay 演练表明,我们已经开始这样做了。
喜欢它,讨厌它?请告诉我们
© 2012 1542-7730/12/0900 $10.00
最初发表于 Queue vol. 10, no. 9—
在 数字图书馆 中评论这篇文章
- 微软的协议文档计划
2002 年,微软开始了验证其 Windows 通信协议的大部分技术文档的艰难过程。