清除分布式系统漏洞
随着我们对分布式系统了解的不断深入,我们发现了各种各样的故障方式。更具体地说,我们发现大型系统或分布式系统中,部分组件发生故障的可能性非常多。
既然任何规模的系统都不可避免地会出现故障,我们就应该更好地理解它。到目前为止,我们一直在比较抽象地讨论不同类型的故障和缺陷。现在是时候更具体地探讨一下了。当然,我们大致了解系统中可能出现的各种问题类型和模式,以及它们为何会成为问题(但又不可避免)。但是,我们如何才能以更具体的方式理解系统中的这些缺陷呢?
为了做到这一点,我们需要更深入地思考,在我们每天接触的系统中,无论是作为软件的消费者还是开发者,故障都会以不同的方式呈现给我们。对我们大多数人来说,系统中的故障通常表现为漏洞。然而,漏洞呈现的方式会极大地影响我们对它的理解。
那么,我们究竟会遇到哪些类型的漏洞?它们又会如何影响分布式系统的故障呢?嗯,这就是我们即将解开的谜团!
过去的(硬件)故障
在深入探讨当今的漏洞之前,让我们先快速回顾一下过去。思考系统中的故障和缺陷很容易让人感到不知所措,因此,在深入研究之前,我们应该花点时间了解一下计算机领域漏洞的格局这些年来发生了哪些变化。
直到20世纪80年代,计算机领域的主要关注点都集中在硬件上。更具体地说,当时的研究重点在于如何全面提升硬件性能。这主要是因为在很多方面,硬件都是主要的制约因素。例如,如果我们想让机器运行得更快、性能更强,就需要更大的硬件;这是容纳所有必要电路的唯一途径!而如果我们想要更多电路——每个电路本身就已经相当庞大——那么我们也必须做好应对它们耗电量大、发热的准备。
这些问题开始凸显出几十年前系统中可能出现的一些显而易见的潜在故障。我们都知道,硬件故障——例如电路过热或网络线路问题导致大范围断网——是造成硬件失效的根本原因。如果硬件的任何部分出现故障,都可能导致系统停机,而停机会降低系统的可靠性。直到上世纪80年代,硬件故障都是一个真实存在且十分普遍的问题。
但如今情况已大不相同。与四十年前相比,我们因硬件故障导致的停机时间大大减少。多年来的不懈努力,使我们如今日常使用的硬件得到了显著改进!过去三十年间,电路尺寸不断缩小,使我们能够在更小的空间内集成更多电路,这些电路产生的热量更少,能耗也大大降低。电路的生产也变得更加便捷和经济,从而降低了整体成本。这也使得我们能够制造出更小巧的设备,例如笔记本电脑、平板电脑和智能手机等等。
但这并不意味着硬件就完全没有问题!即使是内部电路较小的微型设备也会出现硬件故障。网络问题导致的停机仍然可能发生,尽管其发生频率已显著降低。硬件硬盘仍然容易出现故障,这使得读取(更不用说写入)数据变得棘手。当然,硬件的改进并不意味着它不需要维护和升级;由于这些仍然是必要的,因此仍然会导致计划内停机。
总的来说,硬件方面的变革对计算而言总体上是积极的。那么,既然硬件已经改进……还有什么因素会导致分布式系统故障呢?当然是我们的软件老朋友啦!
即使在经过最充分测试的系统中,软件故障也会导致大量的停机时间。我们把这些“故障”称为:漏洞。
尽管硬件不断改进,但分布式系统的软件缺陷仍然是导致意外停机和计划外停机的主要原因。许多研究估计,系统中 25% 到 35% 的停机时间是由软件代码中的缺陷造成的。
这个故事有趣的地方在于,即使在那些相当成熟且拥有严格测试流程的系统中,研究也发现,软件相关的实际停机时间比例实际上从未真正降低 到25%以下!即便经过精心设计的测试和质量控制,似乎仍然有一些漏洞存在。
当前软件问题
更成熟的系统(例如经过严格测试的系统)中仍然存在的缺陷也称为残留缺陷,它们可以分为两大类:
- 玻尔虫(Bohrbugs),以尼尔斯·玻尔和欧内斯特·卢瑟福的原子核模型命名,以及
- 海森堡(Heisenbugs)这个名字源于对维尔纳·海森堡的海森堡不确定性原理的戏仿。
许多计算机科学家都研究过这两种漏洞;其中最著名的三位是吉姆·格雷、布鲁斯·林赛和安德里亚(“安妮塔”)·博尔,我们稍后会了解他们的研究成果。在这两种不同的“残留”漏洞中,一种显然比另一种更容易理解。所以,我们先从容易理解的那种漏洞开始吧!
玻尔漏洞(Bohrbug)是大多数(甚至所有?)程序员在修改软件时都会遇到的一种漏洞。玻尔漏洞是指在特定条件下可以可靠复现的漏洞。例如,如果我们注意到某个软件中存在漏洞,并仔细观察了漏洞发生的具体情况,如果它是玻尔漏洞,那么我们就可以通过重现相同的情况来复现它。
Bohrbug 很容易定位到代码库的特定部分。作为开发人员,这真是一大福音,因为这意味着我们可以可靠地找到并修复Bohrbug,尽管它可能很烦人!
有趣的是,当吉姆·格雷和布鲁斯·林赛在更成熟的系统中研究玻尔漏洞时,他们提出,随着系统变得更老更稳定,这些可重复的小漏洞的出现频率实际上会降低。
然而,安妮塔·博尔的研究对此进行了更细致的阐述。她发现,随着系统稳定性的提高,博尔漏洞的比例并非持续下降;相反,她的研究表明,每次系统升级或计划维护后,博尔漏洞的比例都会略有上升,因为系统的重大变更仍然极有可能引入可复现的漏洞。
值得庆幸的是,尽管这些系统级变更可能会引入新的Bohrbug,但至少它们可以被重现(并有望被修复!)。然而,在软件世界里,事情并非总是如此简单(当然)。有些bug的表现并不总是相同的……事实上,当我们尝试调查它们时,有些bug的表现似乎有所不同!
处理棘手的、分布广泛的漏洞
有一种漏洞与分布式系统尤为相关,而现在,我们终于要在本系列文章中正面探讨它了。我说的当然是海森堡漏洞!
对于程序员来说,处理海森堡bug(Heisenbug)可能非常令人沮丧。这种bug在仔细观察时会表现出不同的行为。当你开始调查海森堡bug时,它的表现形式可能会发生变化。在某些情况下,当海森堡bug被调试时,它会完全消失。而在某些情况下,即使你试图重现某些条件来复现bug,它却根本不会出现!是不是很令人沮丧?
例如,在生产环境中,数据结构空间不足或程序的一部分溢出已分配内存之类的错误可能不容易在本地或测试中重现;然而,这种错误可能会导致系统崩溃,而且后果非常严重!
这正是海森堡漏洞难以理解的部分原因。它们极难理解,因为很难真正定位和确定它们的根源。而且,由于它们难以可靠地复现,因此很难识别,也因此很难真正解决!
海森堡漏洞与分布式系统尤为相关,因为它们更容易在分布式系统中出现,而不是在本地化的集中式系统中。这类漏洞实际上预示着系统中在漏洞显现之前很久就已存在的问题和故障。
海森堡漏洞通常是一个危险信号,表明系统在一段时间前就出现了其他问题,而现在才显现出来,并且恰好以这种漏洞的形式显现出来。
实际上,海森堡病毒只是一个更早出现的问题的长期延迟的副作用。
在更成熟的分布式系统中,导致重大故障和系统崩溃的并非玻尔漏洞, 而是海森堡漏洞。深入思考后,这一点便不难理解:分布式系统中存在众多运行部件,以及相互依赖的众多节点。看似源自系统某个节点的故障,实际上可能与源自其他节点但已传播至整个系统的故障相隔三个节点。玻尔漏洞易于复现、定位和分析,而海森堡漏洞则更难理解,也更难修复。
安妮塔·博尔——我最近最喜欢的残存缺陷研究员——在她的研究中发现,许多工程师很难理解海森堡式缺陷,而且试图修复海森堡式缺陷实际上会造成比最初更多的问题!所以,如果你一直觉得海森堡式缺陷是些难以捉摸的小家伙,难以对付,别担心;研究结果也印证了你的看法!
资源
分布式系统中的软件故障非常有趣,值得深入学习。有很多关于如何处理和防范系统中的海森堡漏洞的研究和文章。如果您有兴趣了解更多,请查看以下资源!
- 可靠的分布式系统:技术、Web 服务和应用,作者:肯尼斯·伯曼
- 电脑为什么会停止运行?我们该如何解决这个问题? ——吉姆·格雷
- 分布式系统导论,华盛顿大学
- 海森堡和玻尔堡:它们为何不同?,理查德·马丁(?)
- 保护应用程序免受海森堡漏洞的侵害,克里斯·霍布斯
文章来源:https://dev.to/vaidehijoshi/weeding-out-distributed-system-bugs-9c8