The Swiss Cheese model, pt. 1

Marcin Wichary

瑞士奶酪模型(上)

原文由 Marcin Wichary 发布,订阅该博客

你听说过瑞士奶酪模型吗?在解释复杂系统如何失效时,时常会看到它。示意图通常是这样的:

它的核心思想是:即便你有多层安全防护——就像叠在一起的多片奶酪——每一片上也总会有漏洞。通常,某一片上的洞会被前一片或后一片的实心部分挡住。(比如,汽车在你没有挂入 P 档时就不会让你拔出钥匙——又比如,你不小心拉着手刹就起步,车会立刻向你发出警报。)但偶尔,这些漏洞会恰好连成一线,酿成更大的灾难。

这个模型被用于分析过去的事故,也被用于预防未来的事故。它既有支持者,也有反对者。要谈它的具体应用并不容易,因为最常被提到的例子都触目惊心。我在自己的书里写过Therac-25,那一章无论是调研还是写作都让人十分难受。其他常被引用的案例同样令人压抑:切尔诺贝利挑战者号特内里费空难深水地平线爆炸事故

但我还是想分享这个模型,因为在我看来,它同样适用于 UI 设计,有时能帮我思考那些细微之处是如何累积成整体效果的。

在这第一部分,我们先从一个更传统的例子讲起,不过它没那么惨烈。主角是金融服务与交易公司奈特资本集团(Knight Capital Group)。关于事故经过,我直接引用Henrico Dolfing的总结:

2012 年 8 月 1 日早上,奈特资本集团像往常一样开启系统,准备迎接一个例行的交易日,然而几分钟内,公司就开始向美国股市发出海量错误订单,在几十只股票上高买低卖,其交易模式完全违背经济逻辑,也无法通过常规手段叫停。起初看似异常的市场波动,很快演变成这家美国最大做市商之一内部的系统性故障,其算法以交易员和工程师都无法实时理解的方式运行。[…]

大约 45 分钟后,问题才被发现、系统被关闭,此时奈特已在 154 只股票上产生了超过 400 万笔成交,涉及约 3.97 亿股,累积了价值数十亿美元的持仓,造成超过 4.6 亿美元的亏损[…]。这次事件的规模不仅体现在财务上,更体现在结构上——一次部署失误竟在整个系统中扩散,而该系统承担着美国股市相当大比例的交易量。[…]

事情的经过是这样的。

很久以前,公司开发了一个相当不起眼、名为 Power Peg 的功能来自动化处理部分交易。该功能使用了一个通用的共享限流器,在所有预定交易完成后就会让它停止执行。使用几年后,该功能在 2003 年被废弃,不再使用,但关键在于,代码从未被真正移除。

在 2003 年至 2012 年之间的某个时候,限流器功能得到了升级,旧代码不再与之兼容。所有在生产环境中的代码都已重写以适配新的限流器,唯独 Power Peg 没有,因为它早已被废弃,当时已不再使用。

2012 年,公司开始编写一套新的自动化交易程序。开发者决定复用之前用于激活 Power Peg 的同一个软件标记。当时大家都知道旧代码依然存在,但设想是新程序会覆盖掉旧代码,因此复用的标记只会触发新代码。

2012 年 7 月,新代码完成,公司开始在所有服务器上安装,以覆盖 Power Peg。公司本打算将新代码部署到全部八台服务器上,但一次失误导致它只部署到了其中七台。

没有人发现这个错误。

到这里,你已经能把整件事拼凑起来了。想必读到这里,许多人已经随着每一段的推进越发感到揪心。

8 月 1 日,新功能的标记被开启。七台服务器上一切正常,但在第八台服务器上,这个标记唤醒了沉睡的旧代码,并立即开始执行。由于旧代码与新的限流器不兼容,它完全不受限制,在不到一小时内级联产生了数百万笔交易,并造成了大量连带损害;随后,市场对公司亏损超过 4 亿美元的消息作出反应,导致其股价暴跌。

哦对了,前面还没提——这次故障要了这家公司的命。(准确说,最后是以合并收场,但那更像是在奈特资本集团濒临倒闭后为保全颜面而采取的做法。)

瑞士奶酪模型在这里是如何体现的呢?你可以把它看作五片奶酪上的五个洞:

  • 没有真正移除旧代码是个错误
  • 复用同一个标记是个错误
  • 没有将代码部署到全部 8 台服务器是个错误
  • 没有安排复核部署的流程、让人二次检查是个错误
  • 在常规限流器失效时,没有自动检测(甚至自动叫停)失控进程的机制也是个错误

理解这个模型的关键在于,单看其中任何一个,客观上都只是一个小错误,本应被其他几层防护挡住。事实上,即便其中四个同时发生,也未必会酿成灾难。

但在这一次,五个错误恰好完美地对齐了。

许多对此类事故的分析会把责任归咎于链条中的某一个环节——在这个案例中,往往是未能将代码正确部署到八台服务器上的系统管理员——但这主要是因为我们偏爱有个人主角的故事,而不太擅长理解系统的故事。(就连《星际迷航》都给博格人加了个女王。)

这起事故后来被戏称为“ Knightmare ”(骑士噩梦)。在接下来的篇章里,我们会聊更多与我们息息相关的系统案例。

本文章由 muse-spark-1.2-contributor 进行翻译

评论