考虑到我们大脑的工作方式,以下是一些解决复杂性能问题的方案。
译自 The Complexity of Solving Performance Problems,作者 Cynthia Dunlop。
当 Google 的数据库黑带领导者发言时,人们都会认真倾听。Kerry Osborne 在 P99 CONF 2023 上的演讲,“如何提高解决复杂性能问题的能力”,即使在几个月后仍然受到广泛关注。
在一个通常以 15 到 20 分钟的 TED 演讲式会议为特色的会议上,Kerry 的演讲持续了 40 多分钟。但这还不够。Kerry 还有更多专业知识要分享,而 P99 CONF 社区渴望听到他的分享。因此,我们很高兴地宣布 Kerry 将在 P99 CONF 24 上发表后续演讲。
用他自己的话说:
“这是我在 P99 CONF 2023 上发表的演讲的第二部分。前半部分重点介绍了我们的大脑如何在性能领域解决复杂问题,以及我们需要具备/培养的特征才能擅长解决这些问题。最后,我介绍了一些基本的方法,这些方法来自经验和研究。这次演讲,“如何提高解决复杂性能问题的能力:第二部分”,将重点介绍我们可以做些什么来提高解决问题的能力,包括一个几乎万无一失的方法来获得成功的结果。”
由于我们已经开始为 P99 CONF 24 做准备,我们认为现在是回顾 Kerry 原演讲中一些亮点的好时机。
注意:P99 CONF 是一个关于性能和低延迟工程的技术会议。它是虚拟的,免费的,并且高度互动。今年的议程涵盖了 Rust、Zig、Go、C 、计算/基础设施、Linux、Kubernetes 和数据库。演讲者包括 Michael Stonebraker、Andy Pavlo、Bryan Cantrill、Liz Rice、Gunnar Morling、Tanel Poder 和 Ashley Williams。
查看特色演讲者 获取免费 P99 CONF 24 通行证
为什么性能问题如此难以解决
让我们谈谈我们在性能领域试图解决的问题的特征。它们很复杂,对吧?几乎每个问题都有多种解决方案。
如果有人来找我说,“嘿,我的数据库很慢”,那么可能有一百万种原因导致它变慢,或者只是让人感觉它很慢。也可能有很多不同的解决方案可以加快系统的速度。如果有人遇到了更具体的问题,比如“我的 IO 系统很慢”,那么我通常可以应用很多解决方案来改善 IO 系统的性能。
这些解决方案在许多方面有所不同:效益、成本和风险。
效益
大多数人关注效益。例如,如果 IO 系统很慢,我可以尝试通过安装固态硬盘来提高 IO 系统的速度,或者尝试将大型多块读取与单块读取分离,这样我的单块读取就不会因为在大型多块读取的队列中等待而延迟。
我可以通过多种方式来解决这个问题,而每种潜在解决方案的效益可能都不一样。固态硬盘可以将速度提高 10 倍或 100 倍。更改排队机制可能会将速度提高 5 倍。不同的解决方案可以实现不同的效益。这使得问题空间变得复杂。
成本(货币成本、实施时间、机会成本)
另一个变化因素是实施这些解决方案的成本。购买整个固态硬盘系统可能比研究 IO 的排队方式或其他与软件相关的方面要昂贵得多。而且需要考虑多种类型的成本:货币成本、实施时间以及机会成本。实施解决方案所需的时间越长,损失就越大,这可能远远超过货币成本。我们必须牢记所有这些不同的方面,仅仅是在成本方面。
风险
风险也是一个因素。当我们谈论实施系统和生产系统时,你在生产系统上做的任何事情都会带来一定程度的风险。我们通常试图最大限度地降低我们所做任何更改的风险,同时最大限度地提高效益。这至少是这三个领域之间的权衡,而且通常还有许多其他领域。
考虑到这些特征提出性能解决方案
在与利益相关者合作时,我们经常需要解释:“嘿,我们这里有三个或四个潜在的解决方案。我们将推荐这个,原因如下。”在我的团队的报告中,我们经常会包含类似这样的句子:
“以下推荐列表是在紧急性和易于实施性之间取得平衡的结果,略微倾向于紧急性。”
在这种情况下,“实施时间”成本真的很重要。迅速解决这一问题迫在眉睫。其他时候,风险或价值可能会优先考虑。在提出解决性能问题的解决方案时,考虑各种优先级并解释为什么推荐一种解决方案而不是另一种解决方案非常重要。这并不总是关乎最大收益。
你的大脑解决性能问题
在这种情况下,“实施时间”的成本非常重要。迫切需要快速解决问题。其他时候,风险或价值可能优先。在提出解决性能问题的方案时,重要的是要考虑各种优先事项,并解释为什么推荐一种解决方案而不是另一种解决方案。这并不总是关于最大利益。
我们的大脑以两种不同的模式工作,特别是在我们解决问题时:直觉和分析。直觉是我们的大脑在没有积极努力地思考某事时的模式。它是自动的。分析是我们实际努力工作并以专注的方式在我们的大脑中勤奋工作时的模式。
例如,如果你看到这个非常简单的等式,1 1 =,你不会花任何力气去解决它。你从小就知道 1 1 = 2。答案是立即的。这是你的大脑在自动模式下做的事情。
我们的大脑在我们日常活动中一直以这种自动的、直觉的模式运行。不幸的是,当我们处于这种模式时,很多偏差会潜入进来,而且我们经常不知道它们正在发生。
例如,当我看到计算机系统或数据库系统上的一组症状时,我倾向于认为我已经获得了足够的信息——我知道关于问题集的所有信息。通常,情况并非如此。我必须不断提醒自己:“嘿,在你开始尝试解决这个问题之前,可能还有其他你需要关注的事实。”
那么,当我们开始尝试解决性能问题时,我们的大脑中到底发生了什么?
第 1 步:定义问题
在传统的解决问题的方法中,第一步是定义问题。这听起来非常简单,但定义问题实际上比你想象的更重要。我们如何定义问题会显著缩小解决方案空间,因此我们要非常小心地定义问题。
例如,假设我们的问题是我们的用户联系我们说:“嘿,我们有一个每天晚上从凌晨 1 点到凌晨 2 点运行的批处理作业。我们必须在凌晨 2 点之前将最终结果交付给管道中的下一个系统,但该系统不再在那个一小时的时间范围内完成作业。而且看起来 IO 系统是主要问题:它运行缓慢;它没有按照我们习惯看到的方式运行。”
我们如何定义这个问题?
- “批处理过程没有在一小时内完成”是对问题的相当好的概括性描述。
- “我们需要加快 IO 系统的速度,因为 IO 系统很慢”是对问题的非常狭隘的定义。
第 2 步:收集数据
为什么这个问题的定义如此重要?因为我们的下一步是收集数据以了解导致问题的原因。
假设我们的定义是 IO 系统很慢。由于我们的偏见,我们的大脑会自动想要丢弃与导致 IO 系统变慢无关的任何数据。这只是我们大脑的工作方式。他们会贬低这些数据——也许不会完全忽略它们,但肯定会贬低它们,并且不会过多地关注它们。这就是为什么我们如何定义问题非常重要的原因。我们需要以有条理的方式收集数据。
第 3 步:推测问题的原因
在传统的解决问题的方法中,在我们获得一个好的定义和一组好的数据之前,我们必须有心理纪律来推迟这一步。如果我们一想到导致问题的原因就开始推测,我们的大脑就会再次欺骗我们。我们会开始根据这种过早的推测来评估我们看到的任何数据或任何症状的重要性——所以我们必须小心这一点。
第 4 步:列出可能的解决方案
在这里,我们使用我们大脑的创造性部分来尝试提出解决问题的方案。通常,这是我们聚集在一个房间里,与多个人一起头脑风暴,在白板上画图等等的地方。这是一个重要的步骤!我们希望给自己足够的时间来做这件事,并且还要有一个环境,在这个环境中,在建议想法方面,没有任何东西是超出范围的。这不是说“好吧,这是一个愚蠢的想法”的地方。这是把所有东西都抛出来,并列出我们能想到的所有东西的地方。
第 5 步:对可能的解决方案进行排序
第五步是对可能的解决方案进行排序。在这里,我们开始根据成本或风险来排除一些方案。目标是创建一个排序列表,列出我们认为能够以最小的风险和成本提供最大收益的方案。但请记住,优先级各不相同,我们需要权衡这些因素。一旦我们有了这个列表并获得了利益相关者的认可,我们就会尝试按照商定的顺序实施可能的解决方案。
现实世界中的方法
现在,让我们看看性能领域的专家是如何实际处理复杂的性能问题的。
直觉(跳跃式方法)
你可以将直觉方法称为“跳跃式方法”。它的关键特征是我们跳到前面。之前我提到过,很难不去跳到解决问题的第三步,即推测问题的原因。请记住,当我们被拉进某个情况时,我们总会对它有一些了解。
没有人会说“来修好我的系统”,而不告诉你问题是什么,对吧?他们可能只是告诉你它很慢,但几乎总会伴随着一些其他信息。也许是“它很慢,我认为存在 IO 问题”或“它很慢,看起来我们在凌晨两点到三点之间将 CPU 占用率拉满了”。总会有一些信息。这些信息让我们能够尽早开始推测。这是这种方法的主要特征。
这种方法有优点也有缺点。由于我们没有经过一个有条理的数据收集步骤,因此我们经常会错过重要的数据。由于我们没有经过严格的头脑风暴环节来尝试找出所有可能的解决方案,因此我们经常会想出不太有创意的解决方案。
但也有一些优点。由于我们没有投入太多时间,我们的头脑愿意快速放弃某个选项。对于更系统的方法,我们可能会有五个严格排序的选项,然后依次尝试每个选项,直到我们到达列表的末尾。对于直觉方法,我们可能会先检查第一个选项,然后部分测试它,然后发现一些我们在初始阶段没有收集到的其他事实。此时,我们可能会立即跳到第五个选项,因为现在看起来这是最好的方向。
我们的头脑可以接受这种做法,因为我们没有花费很长时间来制定一个系统的方法。我们对重新排序选项以及放弃某个方法都很灵活。
系统方法
对于系统方法,我们基本上是严格按照上面概述的步骤进行。这种方法的关键特征是我们有足够的意志力,将推测步骤推迟到收集完数据之后。
当然,这种方法也有优点和缺点。问题定义得更清晰,更多数据可用,更多有创意的解决方案成为可能。然而,由于投入了更多时间,因此找到解决方案通常需要更长时间。此外,由于我们投入了大量精力,因此我们不太愿意随着时间的推移而调整计划。
结合方法
还有一种第三种“结合方法”选项——对我来说,这是最有趣的选项,也是性能领域经验丰富的人最常使用的方法。
这种方法几乎立即跳到推测阶段。经验丰富的人几乎可以立即识别出一些常见的嫌疑人。如果有人在这个行业工作了一段时间,他们可能见过类似的情况,一些相似的症状,他们可以很快地推测出来。他们的头脑会立即想到,“嘿,我见过类似的情况。我要检查一下这个、那个和另一个。”他们可以很快地做到这一点,然后要么说“是的,就是它”,要么可以将其排除在竞争之外。
这里关键的一点是,如果你发现常见的嫌疑人没有结果,你总是可以退回到非常系统的方法。在你以这种直觉模式开始,四处跳跃之后,这种转变可能很困难。
此外,这种方法看起来非常杂乱无章。如果有人在你的肩膀上看着你,可能会让他们对你的能力失去信心。从这个角度来看,你可能看起来无所适从,不知道自己在做什么。
这种技术被称为“识别优先决策”。它在很多行业或职业中被广泛使用,这些行业或职业具有很高的紧迫性和非常高的风险。例如,想想消防员在试图制定计划来扑灭大型建筑物中的火灾时的情况。生命危在旦夕,他们必须非常迅速地做出决定。航空公司飞行员在紧急情况下也有一个记录在案的清单,他们会按照这个清单进行操作;这基于相同的方法。
建议
在我看来,这种结合的方法通常能为经验丰富的人带来最佳效果,尤其是在紧急情况下。如果通常的嫌疑人出现,这绝对是解决问题的最快方法。有条理的方法比直接的直觉方法更好。对于经验不足的人来说,直觉方法——在事物之间跳来跳去——通常是最糟糕的方法。有条理的方法更好,因为它能给利益相关者带来更多信心。
但是,尽管直觉方法通常非常适合那些没有做过这类工作很长时间的人,但它偶尔也可能是最快的——如果你经验丰富,或者你只是幸运。