太长不读
分布式系统就是一种复杂系统,其活动规律是不可预知和非线性的。
生产环境的动荡,来源于复杂系统内部所固有的“暗债”。见与不见,暗债就在那里,不增不减。
具有“可证伪性”的科学实验,只关注所定义的稳态是否被证伪,而对于具体采取哪种方法保持稳态,不做要求,悉听尊便。
要建立对系统能够承受生产环境的动荡的信心,需要针对生产环境“丰富多彩”的暗债,设计同样“丰富多彩”的防范手段。
一个不断演化的分布式系统的复杂性,只会增加,而不会减少。因为任何不断演化的复杂系统,都拥有偶然复杂性与本质复杂性,两者都不会减少,甚至本质复杂性会随着需求的增加而增加。
引子
对于国外的“网红”技术,国内公司都是要试一下的。继云计算、大数据、人工智能、微服务和区块链之后,混沌工程也引起了国内IT领导们的注意。他们会叫来手下技术骨干说:“试一试混沌工程吧”。
一脸蒙圈的技术骨干自言自语:“啥是混沌工程?和测试啥区别?和故障演练啥区别?”
还好,技术骨干记得Netflix公司是混沌工程的发源地。于是上网搜该公司2017年发表的《混沌工程》报告。结果意外地发现,这份报告在2020年4月已经升级为O'Reilly公司出版的同名动物书了。
2020年4月出版的《混沌工程》动物书
两位作者是原来那份报告的5位作者中的两位,其中Casey Rosenthal在Netflix公司组建了混沌工程团队,并管理该团队3年。而Nora Jones在该团队成立早期,就以工程师和技术负责人的身份加入团队,负责有关工具构建和实施的重要架构决策。
技术骨干仗着英文阅读能力还不赖,翻开了这本动物书,首先查看混沌工程的定义。
混沌工程是在分布式系统上进行实验的学科,目的是建立对该系统能够承受生产环境的动荡的信心。
看了定义,觉得除了“做实验”,好像啥也没说。
技术骨干心里琢磨:“生产环境是不允许引入任何风险的。如果混沌工程是在生产环境上做实验,那风险多大呀。领导会答应吗?该咋做混沌工程?”
让我们看看这本书是如何解答上面这些问题的。
混沌工程是“逼上梁山”的结果
才出龙潭,又入虎穴
2008年8月,Netflix公司数据中心发生了一起重大数据库故障,导致该公司连续三天无法为客户邮寄DVD。这发生在流媒体视频服务普及之前,当时为客户邮寄所租赁的DVD是Netflix的主要业务。
这次故障后,Netflix反思系统架构,认为数据中心内诸如大型数据库和垂直伸缩的组件,导致了单点故障。而如果迁移到云平台,势必会使用具有水平伸缩功能的组件,从而减少单点故障。
很快,Netflix对外宣布,将其基础设施从数据中心迁移到亚马逊AWS云平台。
但才出龙潭,又如虎穴。具有横向伸缩功能的云部署,并没有如所期望的那样,增加流媒体服务的正常运行时长。
究其原因,是因为在2008年,AWS的成熟度要比现在低。那时的云计算既不是一种成熟的商品,也不是如今司空见惯的默认部署方式。那时的云服务确实有很多问题,而其中的一个问题就是实例经常会突然消失,且不会发出警告。
而传统的数据中心很少出现这种形式的故障,因为功能强大的大型机器绝不会无故消失,并且特定机器的种种特性也是一清二楚的。但在云环境中,与数据中心大型机器相匹配的运算能力,会分配到许多小型的标准化商用机器上,所以上述问题会经常出现。
当然,有很多增强系统韧性的方法,可以用来抵御这种形式的故障。比如:
在集群中增加冗余节点
通过增加节点数量,并降低每个节点的相对处理能力,来限制故障的范围
在不同的地区部署冗余节点
自动进行容量伸缩和服务发现等
然而,具体使用哪种方法,使得系统足够健壮以处理实例突然消失的问题,其实并不重要。因为不同系统的上下文,会使得具体方法各不相同。
最重要的,是必须要将这些方法落地。
由于上述实例不稳定的事件发生频率很高,当时Netflix公司的流媒体服务,正面临可用性的下滑。所以在某种程度上,这比单点故障的影响还要恶劣。
但既然上了云,就不好回到过去的数据中心了,所以Netfilx只能被“逼上梁山”。
企业文化,发挥作用
面对这样的困境,Netflix公司独特的企业文化发挥了重要的作用:
Netflix只雇用有过相关经验的高级工程师
公司给所有工程师充分的自由,去做任何必要的事情来完成工作,并为与之相关的后果负责
至关重要的是,Netflix信任那些具体做事的工程师,并把决策权交给他们
管理层不会告诉每个工程师该怎么做工作,而是确保工程师们了解需要解决的问题。之后,工程师们会告诉管理层,他们计划如何解决这些问题。然后他们就动手开始解决
高绩效团队,都具有“认同一致,关系宽松”的特点。 这意味着,如果每个人在团队里,都拥有相同的目标,那么就无需花费太多精力,来进行过程管理、正式沟通或任务管理
在“解决因云环境中的实例经常莫名其妙地消失,而导致系统可用性下滑”这个一致的目标下,工程师们开始各自尝试进行解决。
工程师们试过很多方法。最后发现只有混沌猴能够解决问题,所以就将其保留下来。
混沌猴这个工具有个特点,它们和国内大多数工程师不一样,因为它们从不加班,只在上班时间工作。
在每个工作日的上班时间,混沌猴就会在公司的集群里溜达一圈,扫描一遍。然后随机从每个集群中任意选择一个实例,在工程师们工作的时间,将其关闭,且不告警。
这听起来很残酷,但实际效果却出乎意料地好。
因为工程师们了解混沌猴的习性,所以在做软件设计时,会做到事先防范。
一旦出现故障,也因为事先限制了爆炸半径,所以影响也不大。
混沌猴故障总是发生在上班时间,这样便于很快调动工程师来解决问题。而不必半夜三更把人从被窝里喊起来,睡眼惺忪地解决问题。
更重要的是,因为混沌猴所指出的故障,是发生在生产环境。这能让工程师们暂时停下手上的活儿,集中精力优先解决这些漏洞,从而把上面增强系统韧性的方法,真正落了地。
另外,混沌猴每天出没一次,起到了回归实验的作用,能让系统在韧性方面,不会随着时间的推移而“掉队”。
但在私下里,起初Netflix的工程师并不都欢迎混沌猴,曾经有些人一度对其怨声载道。
但看到上述成效后,越来越多的团队最终开始采纳混沌猴。
刚出虎穴,又入狼窝
然而,2012年圣诞节,AWS一个区域的ELB出现故障,导致该区域的Netflix的用户无法在节日期间,观看流媒体视频。
真是刚出虎穴,又入狼窝。AWS以后要是再出这样的大规模的故障,该咋办?
能否把原来在一个AWS区域内小打小闹的混沌猴,规模化到横跨两个AWS区域?
这样当一个AWS的区域出现故障,那么另一个区域会接替工作。
这可不是个小任务,会涉及不同团队之间的大量技术变更。
Netflix成立了一个高层工作组,负责不同团队之间的协调,来将混沌猴升级为混沌金刚——模拟关闭一个AWS区域。因为还有其他“房客”,亚马逊当然不允许他们真的关闭一个区域。
混沌金刚启动初期,要花几小时,在作战室监控流量。
由于在将流量切换到另一个AWS区域之前,要修复各种服务的缺陷,所以混沌金刚曾经停用了好几个月。
最终,混沌金刚能定期执行,以应对一个AWS区域的故障。
起初,最顺利的AWS区域故障切换,也需要50分钟。随着混沌金刚频繁地执行,对快速执行的期望标准也在提升,最终在2015年实现了6分钟切换。
该咋做混沌工程?
在讨论咋做混沌工程之前,让我们先回答下面5个问题。
啥是混沌工程?
先说一个能说出点名堂的我个人对混沌工程的理解,混沌工程,是Netflix公司当面对具有不可预知的“暗债”的复杂系统时,在“目标一致,关系宽松”的企业文化下,“逼上梁山”的结果。
什么是“暗债”?这个词来源于2017年发表的一篇名为STELLA的报告。这份报告由一群韧性工程专家在聚会后所撰写。就在他们聚会的那几天,这群专家赶上了一场极具破坏性的暴风雪。而那场暴风雪的名字,就是 STELLA。
暗债,指当复杂系统内部子系统间相互作用时,所必然存在的不可预知的漏洞,最终会由此引发系统的意外故障。
再说说上面那个“除了‘实验’貌似啥也没说”的定义。
2015年,Netflix将混沌工程正规化,主持起草了混沌工程原则,并给混沌工程下了定义。
混沌工程是在分布式系统上进行实验的学科,目的是建立对该系统能够承受生产环境的动荡的信心。
“貌似啥也没说”的背后,其实这个定义是大有深意的。
分布式系统就是一种复杂系统,其活动规律是不可预知和非线性的。详情参见我之前撰写的“不可能构建第二个云环境去做测试”和“混沌工程与系统稳定性设计模式”
生产环境的动荡,来源于复杂系统内部所固有的“暗债”。见与不见,暗债就在那里,不增不减
具有“可证伪性”的科学实验,只关注所定义的稳态是否被证伪,而对于具体采取哪种方法保持稳态,不做要求,悉听尊便,这就孕育了混沌猴
要建立对系统能够承受生产环境的动荡的信心,需要针对生产环境“丰富多彩”的暗债,设计同样“丰富多彩”的防范手段。依据是控制论学者艾什比的必要多样性法则(Law of Requisite Variety)——要实现控制,控制系统能够执行的行为的多样性,必须不低于需要应对的环境动荡的多样性
一个不断演化的分布式系统的复杂性,只会增加,而不会减少。依据是著有《人月神话》的那位大神Frederick Brooks的一篇文章中所谈到的两类复杂性(偶然复杂性与本质复杂性),都不会减少,甚至有一类还会增加。
其中,偶然复杂性,是在资源有限的条件下,对相互冲突的限制条件作出权衡后的必然结果。
不存在已知的可持续方法,能减少偶然复杂性,因为资源总是有限的,权衡总是要做出的,暗债总是要欠下的。
而本质复杂性,是满足不断增加的新需求的必然结果。一个不断演化的分布式系统,新需求能少得了吗?
混沌工程和测试啥区别?
两者的运行环境有区别。
测试一般运行在测试环境上,而混沌猴一般运行在生产环境上。因为生产环境必然存在不可预知且与测试环境不同的暗债,所以对测试环境所建立的信心,并不能用在生产环境上。
两者的侧重点也有区别。
测试一般只关注已知的断言是否通过,而混沌工程会更关注发现更多未知的暗债。
混沌工程和故障演练啥区别?
两者的侧重点有区别。
故障演练侧重操练已知的故障应对过程,而混沌工程侧重通过实验发现未知的暗债。
生产环境是不允许引入任何风险的。如果混沌工程是在生产环境上做实验,那风险多大呀。领导会答应吗?
前面提到,暗债是生产系统这个复杂系统所固有且不可预知的。那么即使不人为地引入风险,生产环境也是遍布暗债的。不在生产环境进行最小化爆炸半径的实验,来发现暗债,那么只能任凭暗债在最不希望发生的时刻爆发。
该咋做混沌工程?
借鉴Netflix的实例,可以从“摆正心态、人员主动和试点业务”三方面入手,来启动混沌工程。
摆正心态
承认暗债为复杂系统所固有,而不是一味要求工程师“不能也不该出现失误”。否则在故障面前,大家就只会花大量时间相互甩锅,耽误了发现更多暗债和防范措施。
人员主动
前面说过,根据必要多样性法则,要建立对系统能够承受生产环境的动荡的信心,需要针对生产环境“丰富多彩”的暗债,设计同样“丰富多彩”的防范手段。而技术骨干一个人,是发现不了那么多暗债,并找到那么多的防范手段的。所以,就需要发挥各位工程师的主动性。此时,领导者要创造能调动工程师主动性和创造性的企业文化,来促进工程师更安全地发现与修复更多“花样”的暗债。在修复暗债的过程中,就可以使用文章【分布式系统稳定性设计入门】如果不想总是半夜爬起来抢修生产事故……《发布!》第2版解读所介绍的“分布式系统稳定性设计关键清单”。
试点业务
选择一个出现生产事故频率较高的业务系统,尝试混沌工程。因为事故的反复,出现会让发现与解决暗债的动力更大
基于能反映用户体验的业务稳态行为建立假设,而不是先聚焦于在系统内寻找弱点。因为这样能更利于进行全局优化,让成效更大
为了让暗债浮现出来,设计引入足够多样化的现实世界可能发生的事件,而不是设计那些易于生成但在现实中不大可能出现的事件,以便切中要害。针对每一个所引入的事件,参考上述“分布式系统稳定性设计关键清单”,来进行稳定性设计
可以先从准生产环境入手进行混沌实验,等条件成熟后,再逐渐过渡到生产环境
自动化地持续进行混沌实验,以起到回归实验的效果,持续发现并解决暗债,避免系统随着时间的推移,在韧性方面逐渐“掉队”
设计更安全的实验方式,以最小化爆炸半径,让实验所导致的业务损失降到最低,而不是明知故障难以控制,还要贸然进行实验。如果实验的假设被证伪,那么就遇到了发现新的暗债的好机会。在寻找暗债的过程中,可以参考上述“分布式系统稳定性设计关键清单”,来启发寻找漏洞及修复
作者:吾真本
链接://www.greatytc.com/p/42fb7c051c0c
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。