今天,让我们来讨论一个有趣的主题:复杂系统。
引言
在我的职业生涯中,我曾在许多复杂的环境中工作过。例如,我在优步(Uber)的一家竞争对手公司工作,负责优化网约车中的司机-乘客匹配。这个环境和其他环境一样,在技术上是具有挑战性的。然而,没有什么能比得上,我目前在谷歌的经历所带来的复杂性,在那里的两年时间,重塑了我对复杂性的认知。
在这篇文章中,我们将剖析“复杂性”这个概念本身。接下来,我们将退后一步,理解是什么让某些环境更偏向于复杂(complex)而非繁琐(complicated),然后探讨有效驾驭复杂系统的模式。
繁琐(Complicated) vs. 复杂(Complex)
理解繁琐问题和复杂问题之间的区别至关重要,因为每种问题都需要根本上不同的方法:
繁琐问题虽然错综复杂但可预测。它们遵循结构化、可重复的解决方案。例如,报税是繁琐的,但它是一个结构化和常规的问题,因为流程年复一年基本保持不变。
复杂问题不仅错综复杂而且独特。它们需要适应性的、通常是新颖的解决方案。例如,减缓气候变化是一个复杂问题,因为它需要新的、适应性的解决方案,而现有方法本身无法真正应对其不断演变的挑战。
回到软件工程领域,在那家优步的竞争对手公司,其中一个挑战是为乘客高效找到最近的司机。这绝非易事,但它本身并不复杂。确实,存在许多解决方案,例如应用地理哈希(示例),实施这些解决方案之一就是正确的方法。
在谷歌,我担任站点可靠性工程师(SRE),专注于为谷歌机器学习(ML)基础设施提供动力的系统。在这里,我认为挑战是真正复杂的,因为需要新的范式和调度方法,尤其是在谷歌的规模下。
识别一个系统是繁琐的还是复杂的是非常重要的。确实,我们提到繁琐系统在定义上是可重复的,而复杂系统需要独特和定制化的方法。因此,如果我们试图将通用解决方案应用于复杂问题,可能不会带来有效的结果。
复杂系统的特征
在本节中,我们将讨论五个有助于识别复杂系统的常见特征。并非所有复杂系统都具备所有特征,但它们往往表现出以下特征中的至少一部分。
涌现行为(Emergent Behavior)
涌现行为是指系统的整体行为,无法仅通过单独分析其各个组成部分来预测。
例如,Gemini产生意外结果就是一种涌现行为。虽然我无法透露根本原因,但通过单独分析所有不同的组件,这种行为几乎是无法预见的。
这是复杂系统的一个可能特征:它们的行为方式,很难仅通过观察其部分来预测,这使得它们更难调试和管理。
延迟后果(Delayed Consequences)
复杂系统的另一个可能特征是延迟后果,即行动并不总是立即产生效果,相反,后果可能在很久以后才显现出来。
例如,部署系统的新版本可能会引入一个细微的问题,这个问题可能只在几天甚至几周后才出现。这种延迟使调试变得复杂,因为与即时影响相比,识别根本原因变得更加困难。
在复杂系统中,仅仅依赖即时反馈可能会产生一种虚假的稳定感,导致问题最终爆发时带来重大意外。牢记后果可能需要时间才会显现,在复杂环境中工作时至关重要。
局部优化 vs. 全局优化(Local vs. Global Optimization)
在复杂系统中,优化一个部分并不一定能改善整个系统,在某些情况下,甚至可能使情况变得更糟。
与非复杂系统不同(在非复杂系统中,改进一个部分通常会带来积极的收益),复杂系统要难理解得多。各组件以不明显的方式相互作用,局部优化可能产生难以预测的连锁反应,有时会导致系统层面的负面结果。
这突显了复杂系统的一个关键特征:整体大于部分之和。因此,局部收益并不总能转化为全局改进,在某些情况下,它们甚至可能使整个系统性能下降。
滞后效应(Hysteresis)
滞后效应描述了系统的过去状态如何继续影响其行为,即使原始原因已被消除。
一个说明滞后效应的现实例子是交通拥堵:即使在道路事故被清理后,延误仍然存在,因为车辆仍然聚集在一起。同样,在分布式系统中,故障可能导致级联式减速,即使在根本问题修复后也是如此。确实,依赖的系统可能由于各种原因(如缓存、重试或排队的请求)需要时间恢复。
在复杂系统中,仅仅修复根本原因并不总是足够的。因此,评估系统是否容易出现滞后效应,如果会,则预测其影响,是至关重要的。
非线性(Nonlinearity)
在复杂系统中,微小的变化可能产生不成比例的巨大或不可预测的影响。
例如,在排队论中,系统负载会增加延迟,这是可预测的。然而,当队列接近饱和时,即使请求量增加很小,也可能导致响应时间呈指数级飙升。
复杂系统常常达到临界点(tipping points),行为会突然转变,使得过去的趋势对预测不再可靠。这种非线性意味着,输入可预测地映射到输出的传统线性假设,对于复杂系统的设计、测试和推理并不总是有效的。
小结
总结本节,复杂系统:
请注意,规模本身并不能使一个系统变得复杂:即使小型系统也可能表现出涌现或非线性等复杂行为。
驾驭复杂系统的模式
鉴于这些特征,我们如何在复杂环境中有效运作?以下是我个人认为有效的一些策略。
可逆性(Reversibility)
在处理复杂系统时,我们应尽可能优先选择可逆决策(reversible decisions),即那些如果效果不佳可以撤销的变更。
亚马逊的“单向门 vs. 双向门”(one-way vs. two-way doors)框架很好地抓住了这个理念:
在许多情况下,尤其是在复杂系统中,优先选择双向门能带来更好的结果,因为我们可以进行实验、学习并改进,而不是一开始就过度设计。
话虽如此,并非所有决策都应该是可逆的。例如,像安全策略或合规性相关的变更等选择需要前期承诺。关键在于知道何时应优化速度和迭代,何时应深思熟虑和谨慎行事。
超越即时指标思考(Think Beyond Immediate Metrics)
因为复杂系统并不总是对局部优化做出可预测的响应,所以定义正确的成功指标可能与我们做出的变更同等重要。确实,过分关注孤立的、局部的指标可能会产生一种虚假的成功感,同时掩盖了系统中其他地方无意的负面后果。
为避免这种情况,在进行变更之前,我们应该定义局部和全局指标,以获取系统健康的整体视图。这确保我们不仅衡量关注点直接区域的影晌,而且考虑系统作为一个整体。
精心选择的指标不应仅仅确认局部变更的成功;相反,它们应帮助我们做出更好的决策,并确保在系统层面(而不仅仅是孤立区域)实现有意义的改进。
创新(Innovation)
如前所述,复杂系统通常需要独特的解决方案。由于传统策略可能并不总是适用,我们必须愿意跳出思维定式,拥抱创新。
我记得在谷歌参加的一次早期会议。有人提出了一个在复杂性方面看似荒谬的问题,尤其是考虑到规模。我当时的内心反应是:“这不可能”。但随后,一位队友说:“但我们是谷歌,我们应该能够搞定它!”
这句话让我印象深刻。虽然显然并非每家公司都拥有谷歌的资源,但我认为心态才是真正重要的。当面对一个复杂问题时,我们应该假设它是可解的,然后将其分解、实验并迭代,直到找到前进的道路。
有人可能觉得这部分是老生常谈,但重申一下,复杂问题需要非常规思维。在许多情况下,面对复杂问题时,对创新解决方案持开放态度不仅有益,而且是必要的。
受控发布(Controlled Rollout)
在复杂系统中部署变更时,我们应依靠经过验证的最佳实践来最小化风险。这些包括:
通过利用这些技术,我们减少了故障的爆炸半径(blast radius),提高了对变更的信心,并实现了更快的迭代。
可观测性(Observability)
可观测性是复杂系统的主要支柱之一。我对可观测性的工作定义(主要受Observability Engineering启发)如下:
你能够通过切分(slicing and dicing)高基数(high-cardinality)和高维度(high-dimensionality)的遥测数据,来理解系统的任何状态(无论多么新颖或怪异),而无需发布新代码。
没有可观测性:
在未知因素不可避免的复杂环境中,可观测性至关重要。它使团队能够驾驭不确定性、更安全地进行实验,并获得短反馈回路以持续改进系统。
没有适当的可观测性,变更就只是意见而非基于信息的决策。
模拟(Simulation)
预测复杂系统的行为很少是简单的,有时几乎是不可能的。
我记得一个案例,我们花了大量时间设计一个变更,谨慎地用数据支持每一个假设。然而,由于未考虑到的因素,如潜在变量(lurking variables),该变更最终无效^1^。
有时,与其仅仅依赖预测,一个更有效的方法是在推出变更之前对其进行模拟。有多种方法可以利用模拟测试,包括:
请注意,本节提出的想法也严重依赖于可观测性。
机器学习(Machine Learning)
在复杂环境中,基于规则的方法常常会达到极限,因为要预见所有场景过于复杂。在这些情境下,机器学习(ML)会变得特别有效。
确实,与静态启发式方法不同,机器学习模型可以基于反馈回路持续适应,并从真实世界数据中学习,而不是依赖僵化的、预定义的逻辑。
这使得系统能够:
强大的团队协作(Strong Team Collaboration)
最后但同样重要的是,我相信在复杂环境中,比在任何其他地方都更甚,强大的团队协作是绝对必要的。例如,清晰地传达变更为何复杂、与队友讨论可用选项并权衡利弊,这些都是关键技能。
在复杂系统中,通常没有唯一正确的答案。因此,一个能够有效协作并共同应对模糊性的团队可以产生巨大的影响,最终带来更强大的决策。
最后思考
重申一下,繁琐问题可以用可重复的解决方案解决,而复杂系统则需要适应性和不同的思维方式。这就是为什么识别系统是繁琐的还是复杂的是如此重要:它决定了我们应如何解决问题。
然而,在许多环境中,系统既非纯粹的繁琐,也非纯粹的复杂。某些部分可能遵循结构化、可预测的解决方案,而其他部分则需要适应性和新颖的方法。关键在于学会识别何时需要适应性,何时结构化解决方案就足够了。
作者丨Teiva Harsanyi 编译丨Rio
来源丨网址:https://www.thecoder.cafe/p/complex-systems
dbaplus社群欢迎广大技术人员投稿,投稿邮箱:editor@dbaplus.cn