

简单之道
source link: https://tonybai.com/2023/12/11/simplicity/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Tony Bai

本文永久链接 – https://tonybai.com/2023/12/11/simplicity
已经退居二线的Go语言之父Rob Pike近日发表了一篇名为“Simplicity”的博文,记述了2009年在Google内部一次圆桌会议上发表的演讲内容。Pike老先生在这个时间点发表这篇文章究竟有何深意呢?是对Go语言演进的路线有所不满吗?我们不得而知。不过,这篇文章的内容却是非常值得我们学习,这里我简单翻译一下,供大家参考。
2009年5月,Google举办了一次内部的“设计巫术(Design Wizardry)”小组讨论会,我有幸与Jeff Dean、Mike Burrows、Paul Haahr、Alfred Spector和Bill Coughran一起发表了演讲。以下是我演讲内容的文字稿(略作了修改)。尽管一些细节可能已经过时,但演讲的主题依然具有重要意义,而且如今它可能比以往任何时候都更为重要。
简单胜于复杂。
简单的东西更容易理解、搭建、调试和维护,而且最重要的是更易于理解,因为这会带来其他一切好处。让我们来看看google.com的网页,它只有一个搜索框,你输入查询并获取结果,这个简洁的设计是Google成功的一个关键原因。早期的搜索引擎界面要复杂得多,而现在的搜索引擎产品,要么是模仿我们的设计,要么用户体验很差。
那么,Google搜索引擎(GWS)又是如何运作的呢?我瞥了一眼GWS实例的运行参数列表,里面有成千上万的配置标志和数百个参数,还有一些后端机器的名称、后端配置以及一些特性的启用和禁用。其中大多数参数可能是正确的,但我相信也有一些已经过时或错误的。
所以问题是:一个能设计出google.com这样简洁网页的公司,怎么可能同时设计出复杂庞大的GWS搜索引擎呢?答案是,GWS并非从一开始就被“设计”出来,而是通过有机增长逐渐形成的。有机增长的路径非常复杂,每个部分、每次修改看起来都很简单,但综合起来就变得难以维护。
复杂性是乘法效应的。在像Google这样由多个组件组装而成的系统中,如果你让一个组件变得复杂,那么其中的一部分复杂性就会反映到其他组件中。这就是失控的复杂性。
复杂性也是普遍存在的。
很多年前,Tom Cargill从贝尔实验室的研究部门休了一年的假,加入了开发部门。他加入的团队每个子系统的代码都被打印出来,装订成册放在员工办公室的书架上。Tom发现其中一个子系统基本上是完全冗余的,大部分功能在其他地方已经重新实现过。于是他花了几个月的时间删除了那个子系统,删掉了1.5万行代码,并从所有人的书架上移走了一整本厚厚的代码目录。这样简化了整个系统,减少了代码量、测试工作量和维护工作量。他的同事们都很高兴。
然而,在评估时出现了问题。Tom得知管理层有一个衡量生产力的指标是代码行数。由于Tom在那一年删掉了那么多代码,他的生产力指标直接变成了负数。更糟糕的是,他的团队的整体生产力也变成了负数。他只能沮丧地回到研究部门。
这个故事给他上了一课:复杂性无处不在。简单性没有获得奖励。
你可以对这个故事嗤之以鼻,但我们与此并不相去甚远。谁会因为删除Google的代码而得到晋升呢?我们沉浸在自己拥有的庞大复杂代码中,新员工需要花费大量的精力去理解,我们也投入了大量的资源来培训和指导他们适应。我们为能够理解和修改这些代码而感到自豪。
Google是一个民主的组织,代码对每个人都是透明的,可以查看、修改、完善和增加功能。但是每增加一点东西,复杂性就会增加。引入一个新的库,复杂性就增加了;再加上一个存储封装,复杂性又增加了;在子系统中添加新选项,配置变得更加复杂。如果对核心基础模块(如网络库)进行这样的修改,整个系统的复杂性都会大大增加。
复杂性就这样逐步累积,其代价以几何级数增长。
另一方面,简单需要付出努力——但大部分工作都在前期。设计简单的系统是非常困难的,但一旦设计完成并实施,后续的维护和操作就会更加容易。选择避免复杂性可以使简化系统的好处成倍增加。
举个例子,来看看我们的查询日志系统。虽然它在完美程度上还有待提高,但在设计初期就被定位为——至今仍然是——Google内部唯一解决特定核心问题的系统。正是由于这个原因,它确保了系统的稳定性、安全性、一致性以及大规模的经济效益。如果每个团队都自行构建日志基础架构,Google绝对不会达到现在的规模。
然而,这种思路并没有被广泛应用,各个团队仍然频繁地提出建立新的数据存储系统、工作流系统、代码库、基础架构等等。
这种重复建设和快速增长的复杂性正在拖累我们,因为复杂系统的运作效率较低。
Google有几条重要的工程原则:代码要可读,要可测试,别惹恼SRE(译注:Site Reliability Engineering,网站可靠性工程),要追求速度。
然而,简单性从未被纳入考虑。但实际上,它比上述任何一条都更为重要。更简单的设计意味着更易于阅读,代码更易于测试,对SRE更易于解释和修复问题。
此外,简单的系统运行速度更快。
注意,我强调的是系统设计,而不是代码。有时为了提升性能,确实需要增加代码的复杂性,这可能是无法避免的。然而,复杂的系统从来都不会变得更快,因为调试和交互变得复杂,难以理解。复杂性只会导致低效。
简单性甚至比性能更为重要。复杂性对系统的影响是成倍增加的——增加2%的复杂度只能换来2%的性能提升(或者1%、0.1%等),这完全得不偿失。
等一下,服务器利用率为什么那么低?难道不是因为系统太慢吗?
不是的,利用率低是因为系统过于复杂。我们无法理解系统的性能表现,无论是在单机还是集群环境下。组件之间的交互难以清晰描述。
应用开发人员无法完全理解底层基础架构。
基础架构工程师也无法准确了解网络状况。
很难弄清楚应用程序需要哪些资源,问题层出不穷。
为了弥补这些问题,每个人都在配置中添加各种参数和补丁代码,使得一切变得更加难以调试。
为了确保产品正常运行,我们只能围绕产品建立防护墙,以避免受到外部环境的影响——然而,这只是增加了更多的复杂性。
这是一个死循环。
所以请仔细考虑你正在进行的工作,是否可以将其设计得更简单一些?那个功能真的是必需的吗?通过删除、合并或共享资源,是否可以使整个系统变得更简单?请考虑与其他相关团队进行讨论,设计一个更简单、更统一的架构,避免相互之间的制约。
多研究已有系统的适应性,在此基础上进行改进,而不是从头开始构建。如果发现现有系统无法满足需求,也许问题出在你对需求的定义,而不是系统本身。
如果确实需要开发新的组件,请确保它可以被推广和重用,不仅仅为本地团队提供服务。
构建复杂系统很容易。为了赶进度,编码比重新设计更简单、更快。但是技术债务会不断积累,长期来看必然会失败。
我们的代码库比一年前增加了50%。再过一年呢?五年后呢?
如果不能控制复杂性,总有一天不仅仅是利用率低的简单警告。系统会变得过于复杂、运行缓慢,最终导致彻底崩溃。那将是一场“全面崩溃”的灾难。
“Gopher部落”知识星球旨在打造一个精品Go学习和进阶社群!高品质首发Go技术文章,“三天”首发阅读权,每年两期Go语言发展现状分析,每天提前1小时阅读到新鲜的Gopher日报,网课、技术专栏、图书内容前瞻,六小时内必答保证等满足你关于Go语言生态的所有需求!2023年,Gopher部落将进一步聚焦于如何编写雅、地道、可读、可测试的Go代码,关注代码质量并深入理解Go核心技术,并继续加强与星友的互动。欢迎大家加入!




著名云主机服务厂商DigitalOcean发布最新的主机计划,入门级Droplet配置升级为:1 core CPU、1G内存、25G高速SSD,价格5$/月。有使用DigitalOcean需求的朋友,可以打开这个链接地址:https://m.do.co/c/bff6eed92687 开启你的DO主机之路。
Gopher Daily(Gopher每日新闻) – https://gopherdaily.tonybai.com
我的联系方式:
- 微博(暂不可用):https://weibo.com/bigwhite20xx
- 微博2:https://weibo.com/u/6484441286
- 博客:tonybai.com
- github: https://github.com/bigwhite
- Gopher Daily归档 – https://github.com/bigwhite/gopherdaily

商务合作方式:撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。
© 2023, bigwhite. 版权所有.
Related posts:
</div
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK