航空管制系统冗余

今天英国一些机场再次出现航班延误和取消,原因来自苏格兰Prestwick的空中交通管制中心。NATS后来解释,这次是其系统网络一部分出现Connectivity Issue。不到两周前,英国刚刚发生过另外一次更大规模的空管故障,当时的问题后来被定位到飞行数据系统里一小段软件代码。

image.png

看到这种新闻,一个很自然的问题就是:

这么重要的系统,为什么没有Backup?

航空安全如此关键,难道不能准备两套电脑吗?A系统坏了,马上切到B系统,不就解决了吗?

这听起来非常合理。但真正进入复杂工程系统以后就会发现,“有备用系统”和“系统具有真正的韧性”,其实是两件完全不同的事情。

最简单的Backup,其实很容易

假设办公室里有一台电脑。

硬盘坏了。

换一台备用电脑。

文件有云端备份。

继续工作。

这种Backup非常直观,因为系统本身比较独立。

但空中交通管理完全不同。

它并不是一台电脑。

也不是一个软件。

它更像一张巨大网络。

雷达数据、航班计划、通信系统、控制中心、机场、航空公司、不同地区的管制员,以及大量安全规则全部连接在一起。

一个系统的输出,会成为另外一个系统的输入。

这时候“准备一台备用电脑”解决的可能只是非常小的一部分问题。

真正难的是:备用系统会不会和主系统一起坏?

假设你有两台服务器。

Server A和Server B。

看起来已经Redundant。

A坏了,B继续运行。

很好。

但如果A和B都连接同一个交换机,而交换机坏了呢?

两台服务器一起失去连接。

那就不是服务器冗余的问题,而是网络形成了Single Point of Failure。

于是你再增加两个交换机。

问题解决了吗?

也不一定。

如果两个交换机使用同一个电源呢?

再增加双电源。

如果两个电源来自同一个Substation呢?

再增加发电机。

如果所有服务器运行的是同一个软件,而同一个Bug同时触发呢?

硬件备份再多也没有用。

复杂系统真正困难的地方就在这里:

你以为自己准备了两个系统,但它们可能共享同一个失败原因。

这也是为什么“冗余”不等于简单复制

如果一辆飞机有两台完全一样的计算机,而某个输入数据会让同样的软件同时崩溃,那么两台计算机并没有真正提供独立性。

航空、核电、金融和工业控制系统特别关注一种概念:

Common Cause Failure。

共同原因失效。

系统表面上看有很多层保护,但如果这些保护都依赖同一个东西,一个故障仍然可能同时穿透所有层。

比如两个Backup放在同一个机房。

火灾以后一起消失。

两个数据库放在不同服务器。

但管理员执行了同一个错误脚本。

两套软件跑在不同电脑。

但代码完全一样,Bug也完全一样。

所以真正高可靠系统的设计目标不是简单问:

有没有Backup?

而是问:

这些Backup到底有多独立?

但完全独立又会带来另外一个问题

成本会快速上升。

假设我们要求英国空管系统拥有两套完全独立的网络。

不同服务器。

不同软件。

不同通信线路。

不同电源。

不同数据中心。

甚至最好不同的软件团队开发。

理论上当然可以让系统更加可靠。

但意味着什么?

几乎相当于同时建设两套完整的国家级空管基础设施。

而且第二套系统平时可能几乎不用,却仍然需要每天维护、测试和升级。

这就是可靠性工程里永远存在的现实:

可靠性并不是免费的。

99%的可用率和99.9%的可用率之间差很多。

99.9%和99.999%之间的成本差距可能更大。

最后那几个9,往往是最贵的。

更麻烦的是,备用系统也会老化

我们经常想象Backup是一套放在那里永远不会坏的系统。

现实正好相反。

如果一套设备很少使用,它反而可能在真正需要的时候出现问题。

软件版本落后。

配置没有同步。

证书过期。

硬件已经老化。

操作人员很久没有练习切换流程。

真正发生事故的时候才发现:

Backup启动不了。

所以关键系统不能只是“拥有备用”。

它必须定期测试备用。

这又产生另外一种风险:

测试本身可能把正常系统弄坏。

很多大型IT事故就是这样发生的

真正把系统弄停的,并不是黑客,也不是硬件突然爆炸。

而是一次正常的软件升级。

一个配置更改。

数据库迁移。

网络调整。

安全补丁。

系统维护。

从工程角度看,这其实很好理解。任何Change都会改变系统状态,而大型系统内部存在大量相互依赖关系。

一个工程师可能只是改变一个Network Configuration。

结果某个几十公里之外的系统突然收不到数据。

因为中间存在一条没有人意识到的Dependency。

这也是为什么老系统经常给人一种奇怪感觉:

明明技术已经很旧了,为什么不全部换掉?

因为大家知道旧系统的问题。

却不知道替换过程中会出现什么新的问题。

空管系统尤其不能像普通App一样快速迭代

手机App更新以后出Bug,可以马上发布Version 2.1.1。

航空系统不能这么干。

每一个改变都需要经过验证。

因为失败后果完全不同。

Instagram崩溃两个小时,很烦。

空管系统错误却可能涉及真正的飞行安全。

所以关键系统通常具有一个看起来很矛盾的特点:

越重要的系统,升级越谨慎。

越谨慎,更新速度越慢。

更新速度越慢,又越容易积累Legacy System。

于是系统越来越复杂。

这不是管理者简单“不愿意升级”。

而是安全本身会让变化变得困难。

今天的NATS故障还有一个值得注意的细节

NATS说,当Prestwick出现技术问题以后,为了维持安全,它主动限制了交通流量。

换句话说:

系统没有简单继续运行。

而是降低Capacity。

这其实是关键基础设施非常重要的设计原则。

如果系统不能确定自己是否处于正常状态,最安全的选择通常不是“继续试试看”。

而是进入Fail-safe Mode。

铁路信号失效,列车减速甚至停止。

工业设备失去关键传感器,机器停机。

空管能力下降,航班数量被限制。

从乘客角度看:

为什么一个电脑问题就让我的飞机不能起飞?

从安全工程角度看,答案其实正好相反:

飞机之所以不能起飞,是因为安全系统正在工作。

真正危险的是系统出了问题以后,所有飞机仍然假装什么都没有发生。

这也是为什么可靠性和效率经常互相冲突

航空公司希望多飞航班。

机场希望提高Runway Utilisation。

空管系统希望提高Airspace Capacity。

但安全设计需要Margin。

如果一个系统平时永远运行在99.9%的极限Capacity上,那么一点点异常就会造成巨大连锁反应。

这和高速公路很像。

一条路在30%容量下,即使有一辆车坏在路边,影响不大。

如果已经接近100%容量,一辆车突然停下来,后面很快堵几十公里。

现代基础设施为了提高效率,经常不断减少“闲置能力”。

但所谓闲置,换一个名字其实就是:

Resilience。

我觉得这也是今天很多企业容易忽略的问题

库存看起来浪费。

备用服务器看起来浪费。

多余员工看起来浪费。

备用供应商看起来效率不高。

机器预留Capacity看起来没有充分利用资产。

于是管理不断优化:

减少库存。

减少Headcount。

提高Utilisation。

减少供应商。

合并服务器。

集中数据中心。

短期财务指标确实会变漂亮。

但系统同时也可能变得越来越脆弱。

因为能够吸收异常的Buffer消失了。

工程系统里有一个非常现实的原则

如果一套设备的正常运行范围是0到100%,最好不要长期运行在100%。

假设一台机器长期保持70%负载,还有空间处理波动。

长期99%,一点异常就超过极限。

组织也是如此。

一个团队如果每个人每天都100%利用,理论上效率最高。

实际上任何一个人生病、请假或者突然多一个项目,系统马上崩掉。

所以有时候看到一个团队“还有20%的空闲”,管理者可能觉得浪费。

工程师却可能认为:

这20%就是Safety Margin。

航空领域更容易让人看到这种区别

平时我们不太愿意为“没有发生的事故”付钱。

一个Backup系统运行十年,从来没有真正用过,财务人员可能会问:

为什么每年还要花这么多钱维护?

直到第十一年主系统发生故障。

备用系统接管。

没有飞机发生事故。

然后人们又会说:

其实什么都没有发生。

这就是安全投资非常奇怪的地方。

成功的时候,它看起来像没有创造任何东西。

因为它创造的结果恰恰是:

什么都没有发生。

但另一方面,也不能简单因为今天出现故障就断言系统一定缺少冗余

这是讨论这类事件时很重要的一点。

今天Prestwick的Connectivity Issue到底发生在哪一层?

现有Backup机制是否正常工作?

有没有Single Point of Failure?

哪些流量被自动切换?

这些都需要技术调查。

同样,9月8日的软件Bug虽然来自“一小段代码”,也不意味着整个英国空管系统就是被几行简单程序控制。

复杂系统事故往往就是这样。

一个很小的Trigger,经过大量依赖关系逐渐放大。

最后产生巨大的Operational Impact。

所以“小错误造成大事故”并不说明系统本身简单。

恰恰经常说明系统非常复杂。

这让我想到一个很经典的问题

为什么一个£1的零件,能够让一台价值£1 million的机器停产?

因为系统价值和故障部件价格没有关系。

一条生产线可能包含几百万元设备。

但一个£20传感器坏了,整个系统无法确认位置。

于是PLC不允许机器继续动作。

生产停止。

从财务角度看很荒唐:

因为一个£20零件,每小时损失几万镑?

但控制系统关心的不是那个传感器值多少钱。

而是:

没有这个信号以后,还能不能确定机器处于安全状态?

答案如果是不确定,就必须停。

真正成熟的工程系统,因此不会只问“这个零件会不会坏”

而会继续问:

如果它坏了,会发生什么?

我们能不能检测到?

有没有替代信息?

系统可以继续运行多少Capacity?

维修需要多久?

备件在哪里?

谁有权限切换?

操作人员有没有训练过?

这些问题合在一起,才叫Resilience。

所以Resilience并不是一台Backup Server。

它是一整套系统设计和组织能力。

更进一步说,技术Backup也不能取代人的Backup

假设所有自动系统都失效。

最后往往需要人处理。

但这里又出现一个新的问题。

系统越自动化,操作人员平时越少需要手动操作。

于是人在真正紧急的时候,反而可能最不熟悉手动流程。

航空领域长期都在讨论Automation Paradox。

自动化承