以毒攻毒: Google、Amazon、Netflix如何用混沌工程控制系统风险
越来越多的企业开始使用云存储基础设施,将信息存储在云端而非以前的物理基础设施中。然而,云存储并非万无一失;在网络越来越复杂的情况下,云存储设施的故障也变得更加难以预料。
系统故障给企业带来了代价高昂的损失:98% 的企业表示,一小时的宕机时间将给他们带来超过 10 万美元的损失,一次服务中断有可能让一个公司损失数百万美元。英国航空公司首席执行官说,2017年5月发生了一起技术故障导致数万名乘客滞留,他们公司因此损失了8000万英镑(约合7亿人民币)。
等待下一次系统故障并非解决方案,为了迎接挑战,混沌工程应运而生。
2010年,Netflix的信息存储开始从物理基础设施向Amazon Web Services提供的云基础设施转变。在这个转移过程中,最让企业担忧的事情就是数据丢失而影响流媒体体验的需求。为了对数据丢失或是停机等问题有所预防,Netflix的工程团队创造了Chaos Monkey(混乱的猴子),这就是混沌工程的由来。
混沌工程是一种系统的方法,使得系统故障可以在导致中断之前被识别。通过主动测试系统在压力下如何响应,工程团队可以在故障出现之前识别并修复它们。
用更通俗的方式来说,混沌工程就像“疫苗”:注射少量潜在有害的异物以预防疾病,这种人为的“破坏”其实是有帮助的。混沌工程通过在技术系统中注入危害(如延迟、CPU故障或网络黑洞)来建立这种免疫力,从而发现和修正潜在的弱点。
从Google、Amazon、Facebook、Netflix、Microsoft、LinkedIn等一系列网络公司,到诸如银行、金融等更传统的行业,越来越多的技术公司开始把混沌工程应用于服务器架构的检测中。
混沌实验可以帮助减少意外事件,减轻工程团队应急的负担,增加对系统故障模式的理解从而能改进系统设计,减少严重事故检测的平均时间和重复严重事故。
那么,混沌工程从何而来?混沌工程通过什么原理和方法帮助公司预防系统故障?如果要展开第一个混沌工程实验,你需要怎么做?本文将分享混沌工程的简要历史,演示混沌工程如何为你的系统提供新的见解,并且为你展开第一个混沌工程实验提出了一些建议。以下,Enjoy:
1
为什么搞破坏?
混沌工程的作用
混沌工程最初出现在那些开创大规模分布式系统的互联网公司。分布式系统是一组计算机通过网络相互连接、通信并协调它们的行为而形成的系统。分布式系统存在参与者众多、依靠网络等特点,具有一定的复杂性。为了预测系统失败或出现错误的所有方式,“混沌工程”应运而生。
使用分布式系统的公司把信息存储也置于其中,因此出现了分布式存储系统,也就是通俗所说的“云存储”。
起初,人们对于云存储的认识存在一些谬误,比如网络是可靠的,宽带是无限的,延迟是零等。在意识到以上的认知是错误之后,工程师把这种“错误”放入系统中,例如“包丢失攻击”和“延迟攻击”。认识到这些谬误的存在,很大程度上驱动了混动工程实验的设计。
通过混沌工程的实施,用户、企业和技术本身都能有所获益:
对于用户来说,服务的可用性和持久性的提高,这意味着不会有中断干扰他们的日常使用。
对企业来说,混沌工程可以帮助公司避免巨大的维护成本和损失,提高对工程团队的应急培训,改善整个公司的意外事件管理流程。
而对于技术本身,从混沌实验中获得的经验可以减少意外事件,减少工程团队应急的负担,增加对系统故障模式的理解从而能改进系统设计,缩短严重事故检测的平均时间,减少类似事故的再次发生。
2
混沌工程原理
混沌工程运行经过有计划的实验,这些实验可以让工程团队在实际情况中了解到系统在失败时的表现。
这些实验遵循三个步骤:
你首先要形成一个假设,假设系统在出现问题时应该如何运行。
然后,设计针对性的实验在系统中测试它。
最后,在每一步中计算系统失败的带来的影响,寻找成功或失败的迹象。当实验结束时,你可以更好地理解系统的实际行为。
3
如何展开混沌工程实验

前面已经说到,混沌工程就像“疫苗”,因此不足或是过量都无法起到预想的作用。我们建议循序渐进地展开混沌工程实验,按照以下顺序进行实验:
已知-已知——已经了解并注意到的
已知-未知——注意到但不了解的
未知-已知——了解但没有注意到的
未知-未知——既没有注意到也不了解的
下图说明了这个概念:
                                                      
图片来源:ChaosEngineering: the history, principles, and practice
为了在实践中举例说明这一点,我们将演示如何基于MySQL数据库进行实验。
如下图所示,我们有一个100个MySQL主机的集群,每个主机有多个分片。
在其中的一个区域,我们有一个主服务器、两个副本并使用半同步复制,在另一个区域中,也有一个伪主服务器和两个伪副本。
                                                      
第一步,我们要需要明确哪些内容分别是已知和未知的:
已知-已知:我们知道,副本如果发生宕机,它将从集群中删除,然后将从主服务器克隆一个新的副本,并将其添加回集群。
已知-未知:我们已知克隆会发生,因为我们可以通过日志来确认它成功或失败,但是我们不知道从失败到将克隆有效地添加回集群所需的时间。
我们知道,副本发生宕机5分钟后会收到一个警告,但是我们不知道是否应该调整警报阈值以更有效地防止故障发生。
未知-已知:如果我们同时关闭一个集群的两个副本,我们不知道从现有的主服务器上克隆两个新副本所需的确切时间。但是我们知道有一个伪主副本和两个副本。
未知-未知:我们不知道如果关闭A区域中的整个集群会发生什么,也不知道B区域是否能够有效地进行故障转移,因为我们还没有运行这个场景。
第二步,在明确了已知与未知后,我们设计混沌工程实验,按照以下顺序逐步进行:
已知-已知:关闭一个副本,计算从检测到关闭、删除副本、启动克隆、完成克隆和将克隆添加回集群的时间。在你开始这个步骤之前,把副本从2个增加到3个。报告复制关机故障恢复的平均时间,并按日期和时间细分,以反映高峰时间。
已知-未知:通过上一步,可以知道哪些是“已知-未知”的问题,你就能够了解从副本发生故障到将克隆添加回集群所需的平均时间,以及知道5分钟是否是预防严重事故的适当警报阈值。
未知-已知:在进行这个实验之前,将副本的数量增加到4个。同时关闭其中的两个副本,计算克隆两个新副本需要多长时间。这个实验可能会发现未知的问题,例如,主服务器不能同时处理克隆和备份带来的负载,因此你需要更好地调整副本数量。
未知-未知:关闭整个集群(主副本和两个副本)。这种失败可能会导致严重的意外发生,但你可能还没有准备好。在执行混沌实验之前,请优先考虑处理这个失败场景的应急工程工作。
4
第一个混沌工程实验,有何建议?
计划你的第一个实验
混沌工程中最关键的问题之一是“哪里可能出问题?”通过对这个问题的思考和讨论,我们可以总结系统潜在的弱点和预期结果。类似于风险评估,这可以让你对优先级有所把握:哪些潜在问题更有可能发生或后果更严重。
作为管理者,你可以让你的团队将服务、依赖项(内部和外部)和数据存储等因素写下来,这可以让你对“哪里可能出错”有初步的认识。当你觉得某一项可能存在问题时,注入故障会是一个好的开始。
创建一个假设
你知道哪里可能会出问题,在相应的地方注入了故障。接下来会发生什么?在实验实施前先创建一个假设,会是一个很好的团队思维练习。通过讨论这个场景,你可以在运行它之前对预期结果进行假设,比如这个失败对客户、企业或对你的依赖项有什么影响?
测量影响
要理解系统在压力下运行时的行为,需要评估系统的可用性和持久性。你需要拥有一个与用户相关的关键性能指标,例如每分钟的订单量,或每秒的流量。
根据经验,如果你看到这些指标受到影响,则可以停止实验。接下来是评估失败本身,在这里你希望验证(或反驳)你的假设。最后,你需要检查仪表板和警报,看看是否有意外副作用。
回滚计划
请务必要有一个回滚计划,以防出现问题;但你也要接受,有时即使是回滚计划也可能失败。因此你需要考虑如何扭转这种影响。
完善
在运行第一个实验之后,你可能会遇到两个结果之一:验证了系统对引入的失败是否具有弹性,或者发现需要修复的问题。这两个结果都很好。如果是第一种情况,你增强了对系统及其行为的信心;如果是后者,你则在系统导致停机之前发现了问题。
感受乐趣
混沌工程是一个让工作更容易的工具。通过主动测试和验证系统的故障模式,你将减少操作负担,增加可用性。
在用户体验和用户信息越来越受到重视的当下,停机故障给公司带来的损失可谓巨大,因此无论是互联网公司还是传统行业,都开始将混沌工程的思想纳入到风险控制中。
系统故障不可避免,但对系统故障的提前预测与防范是行之有效的应对措施。与其等待下一次代价高昂的停机,不如首先提高系统对潜在风险的“抵抗力”,通过故意破坏,暴露出可能影响系统和客户的未知问题。
就如同人类要打疫苗才能免除病痛,企业的信息基础架构安全,也离不开混沌工程。

来源:经纬创投