dbaplus社群 9小时前
我在Google当SRE时学到的:如何处理复杂系统
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

文章探讨了复杂系统与繁琐系统的区别,强调了理解这种差异对于选择合适的解决方法的关键性。文章深入分析了复杂系统的五大特征:涌现行为、延迟后果、局部与全局优化、滞后效应以及非线性。 此外,文章还提出了一系列有效驾驭复杂系统的策略,包括可逆性、超越即时指标思考、创新、受控发布、可观测性、模拟、机器学习以及强大的团队协作,旨在帮助读者更好地应对复杂环境中的挑战。

🤔 复杂系统与繁琐系统大不同:繁琐系统结构化、可预测,而复杂系统则独特且需要适应性解决方案。区分两者是有效解决问题的关键。

🧩 复杂系统的五大特征:涌现行为、延迟后果、局部优化不等于全局优化、滞后效应和非线性,理解这些特征有助于识别和应对复杂性。

💡 驾驭复杂系统的策略:可逆性决策、超越即时指标、拥抱创新、受控发布、加强可观测性、模拟测试、机器学习和团队协作,这些方法能有效降低风险,提升决策质量。

原创 Teiva Harsanyi 2025-06-25 07:15 广东

复杂和繁琐,完全不是一个概念。


今天,让我们来讨论一个有趣的主题:复杂系统。


引言


在我的职业生涯中,我曾在许多复杂的环境中工作过。例如,我在优步(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)


在复杂系统中部署变更时,我们应依靠经过验证的最佳实践来最小化风险。这些包括:


    功能开关(Feature flags):动态启用或禁用功能而无需部署新代码,允许安全实验和更快回滚。


    金丝雀发布(Canary release):向生产环境中一个小的、受控的子集进行有限发布,非常适合只有少量生产实例的环境。


    渐进式发布(Progressive rollouts):逐步扩大发布范围,最适合具有多个集群或区域的大规模生产设置。


    影子测试(Shadow testing):在并行环境中使用生产流量运行变更,而不影响真实用户。这有助于在启用变更之前验证其正确性。


通过利用这些技术,我们减少了故障的爆炸半径(blast radius),提高了对变更的信心,并实现了更快的迭代。


可观测性(Observability)


可观测性是复杂系统的主要支柱之一。我对可观测性的工作定义(主要受Observability Engineering启发)如下:


你能够通过切分(slicing and dicing)高基数(high-cardinality)和高维度(high-dimensionality)的遥测数据,来理解系统的任何状态(无论多么新颖或怪异),而无需发布新代码。


没有可观测性:


    系统变得更加脆弱,因为未知问题在造成实际影响前一直隐藏。


    调试意外故障变得异常困难。


    由于缺乏高效的反馈回路,创新速度会减慢。


在未知因素不可避免的复杂环境中,可观测性至关重要。它使团队能够驾驭不确定性、更安全地进行实验,并获得短反馈回路以持续改进系统。


没有适当的可观测性,变更就只是意见而非基于信息的决策。


模拟(Simulation)


预测复杂系统的行为很少是简单的,有时几乎是不可能的。


我记得一个案例,我们花了大量时间设计一个变更,谨慎地用数据支持每一个假设。然而,由于未考虑到的因素,如潜在变量(lurking variables),该变更最终无效^1^。


有时,与其仅仅依赖预测,一个更有效的方法是在推出变更之前对其进行模拟。有多种方法可以利用模拟测试,包括:


    重放过去事件(Replaying past events):如果我们设计系统来记录其所有输入,我们就可以针对新版本重放过去的事件,并分析其影响。这使我们能够以受控方式验证变更,减少不确定性,并改进复杂系统中的决策。


    确定性模拟测试(Deterministic simulation testing):不依赖真实世界数据,我们可以创建受控的、可重复的模拟,在特定条件下对系统行为进行建模。这使我们能够以完全确定性的方式测试系统在各种条件下的反应。


请注意,本节提出的想法也严重依赖于可观测性。


机器学习(Machine Learning)


在复杂环境中,基于规则的方法常常会达到极限,因为要预见所有场景过于复杂。在这些情境下,机器学习(ML)会变得特别有效。


确实,与静态启发式方法不同,机器学习模型可以基于反馈回路持续适应,并从真实世界数据中学习,而不是依赖僵化的、预定义的逻辑。


这使得系统能够:


    检测未被明确编程的新兴模式。

    动态适应变化,而无需持续的人工干预。

    做出概率性决策,而不是依赖严格的 if-else 条件。


强大的团队协作(Strong Team Collaboration)


最后但同样重要的是,我相信在复杂环境中,比在任何其他地方都更甚,强大的团队协作是绝对必要的。例如,清晰地传达变更为何复杂、与队友讨论可用选项并权衡利弊,这些都是关键技能。


在复杂系统中,通常没有唯一正确的答案。因此,一个能够有效协作并共同应对模糊性的团队可以产生巨大的影响,最终带来更强大的决策。


最后思考


重申一下,繁琐问题可以用可重复的解决方案解决,而复杂系统则需要适应性和不同的思维方式。这就是为什么识别系统是繁琐的还是复杂的是如此重要:它决定了我们应如何解决问题。


然而,在许多环境中,系统既非纯粹的繁琐,也非纯粹的复杂。某些部分可能遵循结构化、可预测的解决方案,而其他部分则需要适应性和新颖的方法。关键在于学会识别何时需要适应性,何时结构化解决方案就足够了。



作者丨Teiva Harsanyi    编译丨Rio

来源丨网址:https://www.thecoder.cafe/p/complex-systems

dbaplus社群欢迎广大技术人员投稿,投稿邮箱:editor@dbaplus.cn

阅读原文

跳转微信打开

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

复杂系统 系统思维 软件工程 创新
相关文章