做可靠性的都听过一句话:冗余是解决单点故障的万能药。但今天这个案例会告诉你,冗余这东西,用不好就是自欺欺人。我们一个号称"1+1冗余"的关键系统,在一次故障里整机停摆,领导拍着桌子问:"不是有备份吗,怎么全挂了?"
这个系统是个双机热备的工业控制平台,主用控制器和备用控制器一主一备,理论上主用一挂,备用立马接管,业务一点不受影响。结果真出事那天,主用设备失效了,备用设备不仅没接管,自己也在同一时刻倒下了。两台设备"同时"失效,这概率小到让人怀疑是人为破坏。
我们连夜排查。第一步,把系统架构图摊开,把所有主用路径和备用路径一根线一根线地画出来。第二步,逐点找"交叉点"——看看两条路到底在哪个环节共用同一个东西。第三步,这一找就找出了一串隐藏的共因点:主备两路电源,居然接在同一个配电柜的同一路市电输入上;中间还共用同一台UPS;再往下查,主备控制器用的是同一批次、同一型号的芯片;连网络都走同一个交换机。
复盘故障时刻,真相大白。当天市电闪断了一下,主用和备用因为接在同一路市电上,同时掉电;UPS理论上应该顶上来,可它自己也接在这一路市电上,市电一断,UPS同样失电,根本来不及切换。就这么一个"共用同一路市电"的疏忽,让所谓1+1冗余瞬间变成了0+0。再深挖下去,那批芯片本身还有工艺缺陷,就算电源不断,主备同批同款,早晚也会一起坏。
根因就是教科书里的"共因失效",英文叫Common Cause Failure,简称CCF。多个冗余通道因为同一个失效原因同时失效,冗余就形同虚设。共因的来源很多:共用电源、冷却、网络这些公共资源;同一批次、同一型号、同一供应商的元器件;相同的软件固件,藏着同一个bug;相同的设计错误;甚至相同的环境,比如都在同一个机房、同一个机柜。冗余设计不做共因失效分析,就是拿"看起来有备份"安慰自己。
这里得把几个关键知识点讲透。共因失效有个β因子模型,β表示共因失效在总失效里占的比例,β越大,冗余的有效性越低。冗余架构也有讲究:并联冗余、N+1冗余、双机热备、冷备热备,各有各的适用场景和成本。真正有效的冗余,核心就两个字——独立。电源要独立,通道要独立,最好连软硬件都异构,让两条路在物理上、电气上、逻辑上彻底分开。可靠性框图里,冗余支路的前提假设就是"相互独立",这个假设一旦不成立,后面算的所有可靠性指标都是虚的。
改进措施我们一条条落实。主备电源接入不同的市电回路、不同的UPS,物理上彻底隔离,甚至一台接市电、一台接电池加发电机;关键元器件选用不同供应商或不同型号,做异构设计,避免同批次共性缺陷;主备采用异构软件或固件,不同团队开发或不同实现,杜绝同一个bug同时炸两路;定期做冗余切换演练,真实模拟主路失效,验证备用通道真的能接管,而不是图纸上"应该能接管";最后对整个冗余系统做一轮完整的共因失效分析,把所有交叉点找出来,一个一个消除。
验证阶段我们做了故障注入测试。物理隔离电源、异构器件之后,主动模拟主路失效,备用通道100%正常接管,没有一次掉链子。之后反复复盘,再没出现过"主备同时挂"的情况。系统的可用度从99.9%提升到了99.99%,别看只多了一个9,对关键系统来说,这就是质变。
复盘这个案子,我最想说的是:冗余不是"多放一台就保险"。共因失效会让所有冗余瞬间归零。设计冗余之前,先问自己一句——主备之间,到底还有没有共同的东西?独立性是冗余的生命线,电源要隔离、器件要异构、软件要差异化,缺一条都不算真冗余。还有,定期切换演练比平时喊一百遍口号都有用,备用通道不拉出来遛遛,你永远不知道它是不是纸糊的。
最后送一句话:真正的可靠性冗余,是让两条路彻底不认识彼此。认识得越少,活得越久。 |