聪明的程序员容易做出错误的战略决策 - earthly


不要试图创造一个全局的解决方案,一个一个地解决局部问题,也许模式就会出现,本文阐述了从上而下的过早全局抽象设计容易造成战略决策错误,导致南辕北辙:

有时,努力工作的聪明人会使事情变得更糟。以下故事是基于我对一些真实事件的回忆:
 
安排工作问题
一家中等规模的SaaS公司的一个小型开发者团队有一个问题。他们拥有几个服务,做一些数据加载和转换。
由于一个新客户(客户A)产生的数据量是大多数客户的好几倍,所以这些服务的负荷增加了。

他们设法控制住了这个问题,但第二个问题出现了。
他们增加了数据处理的吞吐量,但事实证明,他们损害了数据的公平性。结果,其他一些客户经常在等待或得到陈旧的结果。
客户A堵塞了工作队列,把其他客户等待堵塞中“饿死”了。
这个问题就像一个操作系统的调度问题,当前只是发生在微服务、分布式系统的背景下。

而这正在造成最糟糕的问题:人的问题:
无视存在某个特殊服务情况下,某个高管现在要求每天对其进行更新。
事实证明,这项服务是使用Postgres表和Kafka主题来进行调度的。
有很多变量需要调整,以获得吞吐量和公平性的正确组合。
调度是很难的。
因此,有人呼吁:谁可以帮助这个系统?公司里其他做类似工作的开发人员对Kafka并不熟悉。最好的办法是让了解这个系统的人去改进它。

因此,团队在公平性和吞吐量之间找到了一个折中的办法:
为了防止进一步的事件发生,Tim被要求调查公司一百多个服务中的排队和工作进度是如何处理的。

Tim是一个非常高级的技术负责人,他很擅长他的工作。
向他提出的问题是:我们如何确保这种情况不会再次发生?如果我们继续发生这种情况,我们就会失去高知名度的客户,以及一些有股东价值的东西。我们需要一个比这更好的解决方案。
因此,Tim研究了所有现有的服务,并开始绘制事情的地图。
结果发现,在所有的服务中,排队和正在进行的工作都以各种可能的方式处理。
他很难对所有事情有一个真正的全局观,但看起来大多数服务各自使用SQS、数据库表或Kafka中某个技术实现排队。
 
一个解决方案
所以Tim提出了一个解决方案:创建一个共享库,你可以用它来满足你所有的队列和消息处理需求。
共享库背后是由Kafka的支持,每个人都将迁移到kafka上面。
这个解决方案的好处是,所有的东西都会一样工作。
如果一个从事某项服务的团队解决了一些工作匮乏的问题,其他人也可以使用这个解决方案,因为它是一个共享的库。
如果一个领域出了问题,其他团队的人也可以伸出援手,因为它在任何地方都是同一个解决方案。

但结果根本不是这样。
 
事情是如何失败的
在以前的世界里,每一个处理数据的服务都有一些不同的做法,这使得系统作为一个整体很难从一个自上而下的角度来理解。
Tim很难理解所有的事情是如何运作的,而且这些不同的子系统中的一些问题,在规模上只会变得更糟。

他的假设是,通过将事情标准化,许多这些不相关的小问题,包括最初的公平问题,都可以一次解决。
但是,这个假设被证明是错误的。
标准化是一个相当大的努力,它解决了一些问题,但总的来说,它使事情运作得不那么好。
 
 
像看一个国家一样看问题
从国家角度看问题:某些改善人类状况的计划是如何失败的?
这涉及到一件事:中央计划的、自上而下的改善世界的策略是如何失败的。
它涵盖了很多集中化的标准化努力,它们都有很多共同点,听起来很像这种'统一队列'的努力。

我最喜欢的例子是关于树木的。
 
科学造林
在19世纪,在欧洲,森林是重要的基本收入。一棵树可以是木材,一棵树可以是木柴,一个国家拥有的每一英亩森林都是有价值的。但有多大价值呢?

森林的问题是,它们包含随机的树木,这是难以辨认的。
你无法在高层次上了解你有哪些树木。你可以把它做成地图,但这很难,而且地图会非常复杂。

有许多不同类型的树,它们都可能对不同的事情有用。
事实证明,现实是一团糟。

所以解决方案是科学造林。让我们制作一张简化的森林地图,其中只有最好的树木类型,并以理想的数量间隔开来,我们将使整个森林符合这一要求。

(顺便说一下,事实证明,"最好 "的树是挪威云杉。它生长得很快,看起来像一棵圣诞树)。

贫穷的生态系统无法支持维持周围农民村庄的野味和药材,他们遭受了经济崩溃。一排排一模一样的树木是植物疾病和森林火灾的完美温床。
维持土壤的复杂生态过程也不再起作用,所以一代人之后,
挪威云杉生长不良,营养不良。

你会认为这将结束一切,但有管理的植树造林仍然流行。
以一种在图表上看起来非常统一但在实践中并不顺利的方式进行中央规划的事情今天仍在继续。

詹姆斯-C-斯科特将这些自上而下的解决方案称为legible系统:
它们在高层次上很容易解释:工作如何在该服务中得到处理?和其他所有的服务一样。那是森林中的什么类型的树?它是一棵挪威云杉,和其他所有的树一样。
但是这种方式与“根据领土建立地图”的做法相反:它属于“让我们拿着我们的地图,让领土更像它”。
 
问题在于,这种对标准化的推动的做法有一个偏见:会抛弃了大量本地的、默契的技术,而选择了一个适合优化自上而下控制的系统。
 
为了简单起见,让我们假设有一个横跨道路的栅栏或大门(切斯特顿的栅栏):
比较现代的改革者高高兴兴地走过去,说:"我不知道这有什么用;让我们把它清除掉。“
而更聪明的改革者会很好地回答。"如果你看不到它的用处,我当然不会让你清除它。走吧,好好想想。然后,当你能回来告诉我你确实看到了它的用途时,我可能会允许你销毁它。"
标准化忽略了切斯特顿的栅栏:

  • 为什么城市发展到有混合使用区?
  • 为什么这项服务使用简单的数据库表进行排队?
  • 为什么挪威云杉通常不在这里生长?

如果你不知道这些问题的答案,那么你的计划很有可能会失败。

 
很难不范的错误
网格规划的城市、现代分区和大规模的建筑项目都重复了科学森林学的错误。
而这个错误很容易说明:它是试图让领土与地图相匹配,而忘记了地图(或建筑图)只是一张地图。
当地的许多情况并没有反映在地图上。

我并不是说这是一个愚蠢的错误,任何人都不应该犯。犯这个错误是很容易的。
如果你想了解几种服务如何处理正在进行的工作,有许多细节需要吸收。作为人类,我们理解这些东西的方式是在它们上面进行抽象,并将细节分组。(过早抽象是万恶之源)
所有这些服务的工作方式之间有什么共同点?你建立起一种理解,然后用这种理解,你试图提出一个解决方案。

像国家一样看待问题告诉我们的是:会提问题很重要,你提出的问题可能是试图提出一个全局性的解决方案。一个全球性的解决方案,必然要忽略当地的条件。
一张地图所排除的东西必须比它所包括的东西多。一个在白板上更容易画出来的解决方案不一定更好。它只是更容易画而已。

回到排队的例子,如果Tim进入一个具体团队,努力解决这个具体问题,然后嵌入另一个团队,解决另一个具体问题,那么可能会出现一些共同点。
也可能没有。也许每种情况都需要一个不同的解决方案。与特定的团队一起实习,你可以了解当地的情况。很多东西并不重要,但有些东西很重要。
  
 

Reddit网友讨论 
不要试图创造一个全局的解决方案,一个一个地解决局部问题,也许模式就会出现。
 
举个例子,在过去十年左右的时间里,许多投资银行试图实现的一件事是在其所有的财务、风险和流动性系统中建立一个统一的数据中心/视图/仓库/任何你想用的流行语,也许更多。
这个想法是,对于每个客户的交易,你应该能够看到所有的交易细节,包括客户的细节,风险数字,以及它如何在银行账户中入账的信息,所有这些都是一次性的。
你可以得到实时的风险数字来快速管理风险,或者你可以为董事会成员、监管机构和审计部门生成精确的、完全协调的会计报告。

要做到这一点,每个系统在发布和消费数据时都需要有某种共同的标准:数据的格式标准化,与之相关的元数据,你要多长时间推送或拉取一次,如果出现异常会怎样,手动更新会怎样,版本管理等等。
上面这篇博文认为这是徒劳的,多年来,我也倾向于这种观点。

可以预见的是,据我所知,没有一家投资银行能做到这一点。他们已经成功地创建了新的标准,但问题是随后就转化为将业务领域和系统一个个地纳入其中。每一个入职都有自己的怪癖和问题。统一的系统最终将所有的数据质量问题、时间问题和系统限制结合起来。划出一个例外意味着这个例外成为一个新的标准,并以某种方式需要与其他所有目前正在工作的系统一起工作。不难想象,需要O(n)甚至O(nm)的额外变通,这取决于一个团队可以抛出多少政治影响力。

当然,统一的系统也会成为一个单点故障。如果你不能监控你的风险,这很糟糕,但想象一下同时失去你的财务报告和客户监控。

我的前雇主,在我离开的时候,至少有4个这样的系统在生产,每个都有不同的准备程度。我毫不怀疑,有几个中层管理人员和企业架构师因此得到了晋升,但由于某些原因,他们似乎从来没有呆过很久......
 
有些程序员本能地自上而下地思考,他们需要学会自下而上地思考。然后是那些本能地自下而上思考的程序员,那些需要学会自上而下思考的程序员:
通过同时从双方解决问题,您可以获得介于整体设计和小规模设计之间的信息流,从而避免了大约 95% 的路径,这些路径会导致您自己陷入困境。
 
我在一家公司工作,该公司大力推动整个公司开发团队的事物标准化……但他们没有制定指导方针和广泛的标准,也没有让团队灵活地在这些指导方针内移动。
不,他们基于(最大的)电子商务平台制定了严格的标准,并迫使每个团队(无论团队规模或项目目标)都遵循这些标准,这导致了一些令人敬畏的情况,例如:

  • 每个 PR 都必须得到三名非管理团队成员的批准。我们的一个团队有两个人,其中一个是经理。
  • 每个员工都会获得 Office 的 E1 许可证——这被认为是足够的。E1 不允许保存电子邮件以附加到工单或打开 CSV 文件……这在我的团队所做的工作中经常出现。
  • DBA 标准是一场噩梦,包括不允许超过五个字符的 ID。我们的一些表有六个字符 ID 字段(大量生成的字段),或者无法保存超过一定大小的数据(这使得我们的日志记录工作有点困难,因为我们记录了整个请求)。
  • 我最喜欢的是设计团队坚持表单的大小不应超过四个字段,如果我们需要更多字段,我们应该有另一个屏幕,用户将被发送到……因为电子商务网站就是这样工作的。

我很高兴离开那个地方,但它确实向我展示了“全局自上而下思考”的危险