UCSC-容错计算笔记-全-

UCSC 容错计算笔记(全)

001:背景与动机 📚

概述

在本节课中,我们将学习容错计算的基本背景与核心动机。课程将介绍为什么我们需要设计高可靠的计算系统,并概述实现这一目标的主要方法。

课程介绍与结构

欢迎来到研究生课程 ECE 257A——可靠计算的容错技术。由于2020年秋季学期采用远程教学,我将录制本课程的讲座。这些讲座也计划用于未来的“翻转课堂”模式,即学生在课前观看讲座,课堂时间则用于讨论和答疑。

本学期,原定的每周两次课程的第一个小时将改为Zoom线上答疑时间,您可以就讲座内容或课程相关问题进行提问。关于本学期的具体课程要求,我将通过课程网站和GauchoSpace邮件进行通知,不会在讲座中详述。

您需要定期查阅两个网站来跟进课程:

  1. 课程网站:ECE257A网页,包含课程要求、讲座日程、作业截止日期和研究项目信息。
  2. 教材网站:我编写的教材草稿可免费在线获取,包含各章节PDF和讲座幻灯片。

课程评估包含两部分:四次作业,以及一篇研究论文及其海报展示。作业有严格截止日期,逾期不候,以便我能及时提供参考答案供您自查。

可靠计算的核心思想

上一节我们介绍了课程的基本信息,本节中我们来看看可靠计算领域的核心思想。

可靠计算领域始于20世纪60年代,由美国宇航局(NASA)等机构推动,旨在为航天器设计能在恶劣环境下长期无维护运行的高可靠性计算机。到了80年代,“可靠计算”这一更广泛的术语被提出,因为它不仅涵盖“容错”,还包括故障预防、错误预防等技术。

可靠系统的设计有两个关键理念:模块化冗余

  • 模块化:系统由相互隔离的模块组成。当一个模块出现问题时,问题不会扩散到其他模块,从而将故障影响限制在局部。
  • 冗余:系统拥有超出其绝对必要需求的资源。当部分资源失效时,系统仍能利用剩余资源维持关键功能的运行。

一个形象的比喻是悬索桥的缆绳:它由多股钢丝(模块)绞合而成(冗余)。即使其中几股钢丝存在缺陷或断裂,只要剩余钢丝的强度足够,整座桥依然安全。

可靠计算的重要性与挑战

理想情况下,可靠设计的技术应融入所有计算机工程课程,而非单独开设。但现状是,许多编程和逻辑设计课程并未系统讲授提高系统可靠性的方法。因此,本课程将集中介绍一系列技术,使您能够将所学应用于构建更可靠的系统——无论是软件、并行计算机还是逻辑电路。

然而,设计可靠系统面临巨大挑战,主要源于系统日益增长的复杂性。无论是软件(如操作系统代码行数激增)还是硬件(如处理器晶体管数量爆炸式增长),复杂性都使得彻底测试和确保无误变得几乎不可能。因此,最可靠的方法之一是尽可能保持系统简单,只包含绝对必要的功能。

故障与可靠性模型

当系统表现与预期不符时,我们就说发生了故障。故障不一定是灾难性的崩溃,也可能是输出一个错误结果这样的细微错误。

在结构工程中,我们通过引入安全系数(例如,计算需要5平方英寸截面的梁,实际使用20平方英寸)来应对不确定性和潜在缺陷。在计算机系统中,我们无法简单地“增加代码行数”来提高可靠性,而是需要通过冗余来改变系统的可靠性模型。

对于一个由n个相同组件构成的非冗余系统,其在一段时间T内的可靠性R(T)可以用以下公式描述:
R(T) = e^(-n * λ * T)
其中,λ是每个组件的失效率。

为了提高R(T),我们只能尝试减少组件数量n、缩短运行时间T或使用失效率λ更低的(更昂贵的)组件。但这些调整空间往往有限。因此,根本的解决方案是通过引入冗余来改变这个可靠性公式本身。例如,系统有10,000个组件,但只需9,000个即可运行,那么其可靠性将显著不同。

案例研究:分布式文件可用性

让我们通过一个简化案例来理解冗余如何提升可用性。假设用户从站点1访问存储在站点3的文件,需要连接链路和站点本身都正常。设站点可用性为S=0.99,链路可用性为L=0.95,则单副本可用性为S * L = 0.9405,即大约有6%的时间无法访问。

为了提高可用性,我们可以采用以下策略:

  1. 文件复制(100%冗余):在另一个站点(如站点0)保存文件的完整副本。用户可通过任一副本访问文件。新可用性公式为:1 - (1 - S*L)^2。计算可得可用性提升至约99.65%。
  2. 文件三副本(200%冗余):保存两个额外副本。可用性公式更复杂,但可提升至约99.98%。
  3. 纠删码(67%冗余):将文件分割成5个编码块,其中任意3块即可重构原文件。这种方法能以更低的冗余度(仅67%)实现很高的可用性(约99.92%)。

以下是纠删码的一个简单示例:假设文件包含三个数字A, B, C。我们构造一个二次多项式f(x) = A*x^2 + B*x + C,并计算f(0), f(1), f(2), f(3), f(4)得到五个值。任意三个值都足以通过插值唯一确定多项式系数A, B, C,从而恢复原文件。

可靠计算的多层模型

为了精确描述系统中的问题,我们引入一个七层模型。系统从理想状态开始,可能因各种原因向下层状态退化,直至最终故障。同时,我们也可以通过内置的容错机制使其向上层状态恢复。

以下是各层状态的定义:

  • 缺陷:物理层面的不完善。
  • 故障:逻辑层面的偏差。
  • 错误:信息或系统状态层面的不正确。
  • 功能失常:子系统或架构层面的异常行为。
  • 服务降级:服务质量低于预期。
  • 故障:系统无法交付预期服务。

这个模型是理解本课程结构的基础,教材也相应分为处理缺陷、故障、错误、功能失常、降级和故障等不同部分的七个板块。

可靠系统的分类

根据应用需求,可靠计算机系统主要分为三类:

  1. 长寿命系统:如航天器计算机,要求极高的可靠性,在无维护条件下长期运行。
  2. 高完整性系统:用于安全关键应用,如航空电子或医疗设备,必须保证故障安全,即发生故障时不会导致灾难性后果。
  3. 高可用性系统:如电子商务网站或云服务平台,需要极高的可用性(如99.999%),即使部分组件失效,整体服务也不能中断。

总结

本节课中我们一起学习了容错计算的背景与核心动机。我们了解了为什么需要专门的技术来设计可靠系统,探讨了通过模块化和冗余提升可靠性的基本思想,分析了系统复杂性带来的挑战,并通过分布式文件案例看到了冗余技术的实际效果。最后,我们介绍了描述系统问题的多层模型和可靠系统的不同分类,为后续深入学习具体技术奠定了基础。下一讲,我们将详细探讨可靠性的各种属性。

002:可靠性属性 📊

在本节课中,我们将学习如何量化和比较系统的可靠性。我们将探讨一系列用于衡量系统可靠性的关键属性和指标,包括可靠性、可用性、可执行性、安全性等。课程将从概率论基础概念回顾开始,逐步深入到各种可靠性模型和评估方法。

概率论基础概念回顾 🔍

上一节我们介绍了课程概述,本节中我们来看看理解可靠性属性所需的一些基本概率论概念。这些概念是后续量化分析的基础。

概率密度函数 f(t) 定义为随机变量 X 在区间 [t, t+dt] 内取值的概率除以 dt。其公式为:
f(t) = P(t ≤ X < t+dt) / dt

累积分布函数 F(t) 是概率密度函数从0到t的积分,表示随机变量 X 小于或等于 t 的概率。其公式为:
F(t) = ∫₀ᵗ f(x) dx

期望值 E[X] 是随机变量 X 的加权平均值。对于连续变量,其公式为:
E[X] = ∫_{-∞}^{∞} x * f(x) dx
对于离散变量,其公式为:
E[X] = Σ_k x_k * P(X = x_k)

方差 Var(X) 衡量随机变量与其期望值的偏离程度。其公式为:
Var(X) = E[(X - E[X])²] = E[X²] - (E[X])²

协方差 Cov(X, Y) 衡量两个随机变量之间的线性关系。其公式为:
Cov(X, Y) = E[(X - E[X])(Y - E[Y])] = E[XY] - E[X]E[Y]

以下是几种常见的概率分布:

  • 均匀分布:密度函数在某个区间内为常数。
  • 指数分布:密度函数呈指数衰减,常用于模拟无老化现象的电子系统故障。
  • 正态分布:密度函数呈钟形曲线。
  • 二项分布:正态分布的离散版本。

保护层与独立性假设 🛡️

在构建高可靠性系统时,常采用多层保护的设计思想。然而,关于这些保护层存在一个常见的误解。

设想使用多层坚固织物制作防弹背心。每层织物都有一些代表缺陷的孔洞。如果这些孔洞的位置完全随机且各层独立,那么子弹恰好穿过所有层对齐孔洞的概率极低。例如,若每层有1%的概率无法阻挡子弹,且各层独立,则四层都无法阻挡子弹的概率为 0.01⁴ = 10⁻⁸

然而,独立性假设是一个很强的假设。在实际系统中,子系统故障可能并非统计独立,而是存在共因故障。例如,所有子系统连接至同一个电源,电源故障会导致所有子系统同时失效,这就是一个单点故障

一个著名的例子是1986年的ARPANET网络。它在纽约和波士顿之间铺设了7条独立的租用线路,假设它们同时失效的概率极低。但实际上,这7条线路都经过同一条物理光缆。当一台挖掘机意外挖断这条光缆时,所有7条线路同时中断。这个例子警示我们,在使用独立性假设进行概率计算前,必须仔细验证其有效性。

可靠性及其度量 ⏳

可靠性是系统在时间区间 [0, t] 内保持正常运行状态的概率,适用于不可修复的双态(正常/故障)系统。

系统在时间 t+dt 仍然正常的条件是:它在时间 t 正常(概率为 R(t)),并且在接下来的短时间 dt 内不发生故障(概率为 1 - λ dt)。由此可得微分方程:
dR(t)/dt = -λ R(t)
解此方程,得到指数可靠性定律
R(t) = e^{-λt}
其中 λ 是常数故障率。对于由 n 个相同组件构成的系统,系统故障率为

平均无故障时间 是系统发生故障前平均运行的时间,定义为可靠性函数曲线下的面积:
MTTF = ∫₀^∞ R(t) dt
对于指数分布,MTTF = 1/λ

除了指数分布,还有其他用于建模可靠性的分布:

  • 瑞利分布:故障率随时间线性增加。
  • 威布尔分布:一个更通用的分布,通过参数 α 可以模拟不同类型的故障率变化(α<1 对应早期故障率下降,α=1 对应指数分布,α>1 对应故障率上升)。

一个使用威布尔分布的例子是回形针弯曲实验。记录回形针在断裂前能承受的弯曲次数,其分布符合威布尔分布,参数 α ≈ 2.6,表明故障率随使用次数增加而上升。

可靠性比较与相关定律 📈

比较两个系统的可靠性时,仅看MTTF可能产生误导。如下图所示,系统1的MTTF可能大于系统2,但在关键的任务时间 T_M 内,系统2的可靠性 R₂(T_M) 却高于系统1的可靠性 R₁(T_M)

因此,我们需要更精细的比较指标:

  • 可靠性差异R₂(T_M) - R₁(T_M)
  • 可靠性增益R₂(T_M) / R₁(T_M)
  • 可靠性改善因子(1 - R₁(T_M)) / (1 - R₂(T_M)) (即不可靠性之比)
  • 任务时间改善因子:对于给定的可靠性目标 R_G,系统2能达到 R_G 的任务时间与系统1相应任务时间之比。

可靠性改善也存在一个类似于计算机体系结构中阿姆达尔定律的现象。假设系统总故障率为 λ,其中一部分 φ 的故障率被改善了 p 倍(即降低为 φ/p),而剩余部分 (λ - φ) 未改善。那么,系统整体的可靠性改善指数存在一个上限,最大改善倍数为 1 / (φ/λ)。这意味着,无论对可改善部分做多大改进,整体可靠性受限于未改善部分的比例。

此外,在可靠性评估中还存在可靠性反转现象。由于我们无法精确获知系统的真实可靠性,只能通过模型计算出一个可靠性的下界。可能出现的情况是:系统A的真实可靠性高于系统B,但模型计算出的系统A可靠性下界却低于系统B的下界。这可能导致我们根据模型错误地选择了实际可靠性较低的系统。因此,开发更精确、更接近真实值的模型至关重要。

可用性 ♻️

可用性适用于可修复系统。系统在运行和故障状态之间切换,故障后可以被修复。

稳态可用性 A 定义为系统长期处于正常运行状态的时间比例。其计算公式为:
A = MTTF / (MTTF + MTTR)
其中,MTTF 是平均无故障时间,MTTR 是平均修复时间。
若故障率为 λ,修复率为 μ,则 MTTF = 1/λMTTR = 1/μ,代入公式可得:
A = μ / (λ + μ)
通常 μ >> λ,因此可用性接近1。

可执行性与安全性 ⚖️

可执行性 适用于性能可降级的“故障软化”系统。例如,一个双处理器系统,双处理器都正常时性能为2,一个故障时性能降为1,全部故障时性能为0。
系统的平均可执行性 P 是各状态性能与其稳态概率的加权和:
P = 2 * P(up2) + 1 * P(up1) + 0 * P(down)
例如,若 P(up2)=0.92, P(up1)=0.06, P(down)=0.02,则 P = 1.90

安全性 关注系统故障对外部(尤其是人员)造成的后果,与可靠性不同。一个系统可以设计成故障安全的,即一旦检测到故障,就进入一个已知的、不会造成危害的状态(如完全关机),尽管这可能意味着它并不“可靠”。

为了量化安全风险,我们引入风险评估概念。风险 R 是事件发生概率 P 与其后果严重程度 C 的乘积:
R = P * C
后果通常用金钱衡量。人类通常是风险厌恶的,即人们更关注小概率的重大损失,而非其期望值,这为保险业提供了基础。

安全模型比可靠性模型更复杂,可能包含正常状态、多个不同危险程度的故障安全状态和不安全状态,以及这些状态之间的各种转换概率。

隐私、安全与总结 🔐

隐私 指防止未经授权披露机密或个人数据。
安全 指防止未经授权修改数据或系统状态(如银行账户信息)。
安全与可靠性、安全性都不同。一个在怀疑被入侵时自动锁定的系统可能是安全的,但不可靠(无法使用),也可能不安全(锁定状态本身有风险)。

量化安全面临挑战。虽然可以像风险评估一样尝试用 概率 × 后果 来建模,但安全威胁(如黑客攻击)往往不是随机的概率事件,而是有目的的恶意行为,这使得为单个系统分配准确的被攻击概率非常困难。如何有效量化安全仍是当前的研究课题。

本节课中我们一起学习了量化系统可靠性的核心属性。我们从概率基础出发,探讨了可靠性、可用性、可执行性和安全性的定义、计算模型及比较方法。关键点包括:理解指数可靠性定律及其适用范围,认识到独立性假设和共因故障的重要性,掌握比较不同系统可靠性的多种指标,了解可用性对于可修复系统的意义,以及区分可靠性、安全性和安全等不同但相关的概念。这些概念和工具为设计和评估高可信赖的计算系统奠定了理论基础。

003:组合建模 📊

在本节课中,我们将要学习组合建模。这是一种用于评估系统可靠性和其他可靠性属性的方法,其核心思想是将系统分解为一系列组合逻辑关系进行分析。

上一节我们介绍了课程的基本框架,本节中我们来看看组合建模的具体方法。

案例分析法

当系统组件较少且连接简单时,可以直接写出可靠性方程。例如,一个由处理器、内存和连接总线组成的系统,其整体可靠性是三个组件可靠性的乘积。

然而,当系统变得复杂时,我们需要更系统化的方法。案例分析法就是一种将问题分解为互斥子情况进行分析的方法。

以下是案例分析法的基本步骤:

  1. 识别系统成功运行所需的条件。
  2. 将系统状态分解为一系列互斥的子情况。
  3. 针对每个子情况,计算系统成功的概率。
  4. 将所有子情况的成功概率相加,得到系统总体的可靠性。

例如,在一个包含主站点和镜像站点的数据访问系统中,我们可以通过分析“主站点可用”和“主站点不可用”这两种互斥情况,来推导出数据可访问性的公式。

串联与并联系统 🔗

串联系统和并联系统是可靠性建模中最基础的两种结构。

串联系统

串联系统由n个单元组成,所有单元都必须正常工作,系统才能正常运行。其可靠性是所有单元可靠性的乘积。

公式R_series = R1 * R2 * ... * Rn

如果各单元的可靠性服从指数分布,其失效率为λ,则串联系统的总失效率是各单元失效率之和。

公式λ_total = λ1 + λ2 + ... + λn

在系统设计中,这引出了“失效率预算分配”的概念。设计经理可以根据总体可靠性目标,将允许的总失效率分配给各个设计团队。

并联系统

并联系统也由n个单元组成,只要至少有一个单元正常工作,系统就能正常运行。其不可靠性(失效概率)是所有单元不可靠性的乘积。

公式R_parallel = 1 - [(1 - R1) * (1 - R2) * ... * (1 - Rn)]

对于并联系统,设定可靠性目标后,可以反向推导出每个单元允许的不可靠性预算。如果单元相同,每个单元的不可靠性约为总不可靠性的n次方根。

重要提示:一个系统是串联还是并联,取决于所考虑的故障模式。例如,四个并联的阀门,对于“卡在关闭状态”的故障是并联系统(一个阀门关闭不影响流通),但对于“卡在开启状态”的故障则是串联系统(一个阀门常开即失去控制)。

建模的风险与覆盖因子 ⚠️

建模存在风险,不准确的模型可能导致脱离实际的结果。例如,在评估飞机客舱失压与氧气面罩系统的联合失效概率时,不同的时间假设会导致数量级差异的结果。过于乐观的模型是危险的,因为它可能高估系统可靠性。

在并联(冗余)系统中,一个关键假设是故障检测和切换到备用模块的过程是完美可靠的。现实中,这个过程可能失败。为此,我们引入“覆盖因子”(C)来建模这种不完美性。

覆盖因子C表示成功检测到故障并切换到备用模块的概率。考虑覆盖因子后,带n个备用模块的并联系统可靠性公式会发生变化。当C<1时,系统可靠性不会随模块数量无限增加,而是会趋于饱和,甚至可能下降。

核心结论:要想通过冗余显著提高可靠性,必须实现很高的覆盖因子,这意味着需要可靠且快速的故障检测与切换机制。

K-out-of-N 系统 🗳️

K-out-of-N 系统要求N个单元中至少有K个正常工作,系统才能正常运行。最常见的例子是“三取二”(2-out-of-3)系统,它使用多数表决器来输出正确结果。

一个经典的K-out-of-N系统(如N个相同单元)的可靠性公式如下:

公式R = Σ (from j=k to n) [ C(n, j) * Rm^j * (1 - Rm)^(n-j) ]
其中 C(n, j) 是组合数,Rm 是单个单元的可靠性。

其变体包括“连续K-out-of-N好”系统和“连续K-out-of-N坏”系统,前者要求至少K个连续单元正常,后者则规定若有K个连续单元失效则系统失效。这些模型适用于如路灯、总线等特定场景。

可靠性框图与故障树 🌳

对于更复杂的系统,我们需要使用可靠性框图或故障树等工具。

可靠性框图

可靠性框图用方块代表单元,连线表示功能依赖关系,从输入到输出的一条连通路径代表系统成功。串联和并联是它的特例。对于非串并联的复杂框图,我们可以使用“案例分析法”或“成功路径枚举法”进行求解。

故障树分析

故障树分析是一种自上而下的演绎方法,从顶层的“不希望发生的事件”(顶事件)开始,逐层找出所有可能导致该事件发生的底层基本事件(故障)组合。

以下是故障树分析的关键步骤:

  1. 定义顶事件。
  2. 识别导致顶事件发生的直接原因(中间事件或基本事件)。
  3. 使用逻辑门(与门、或门等)连接这些事件。
  4. 逐级向下分解,直到所有分支都到达基本事件。

故障树分析的核心是寻找“最小割集”。割集是一组基本事件的集合,它们同时发生将导致顶事件发生。最小割集是其中不能再移除任何元素的割集,它揭示了系统的薄弱环节。

模型层次结构 📈

我们所讨论的模型构成一个层次结构:

  1. 无重复事件的故障树可靠性框图 完全等价,可以相互转换。
  2. 可靠性图 比上述两者更通用,可以表示它们无法描述的一些关系。
  3. 包含重复事件的故障树 是表达能力最强的组合模型,可以涵盖所有其他模型能描述的情况。因此,故障树分析在工业界被广泛应用。

本节课中我们一起学习了组合建模的核心方法。我们从简单的案例分析和串并联系统出发,探讨了建模的风险、覆盖因子的重要性,以及K-out-of-N系统。最后,我们介绍了用于处理复杂系统的可靠性框图和功能强大的故障树分析法。这些工具为我们定量评估和改进系统可靠性提供了坚实的基础。下一讲,我们将进入另一种重要的建模范式:状态空间建模。

004:状态空间建模 📊

在本节课中,我们将要学习状态空间建模。这是一种在组合建模之外的重要建模技术,用于描述系统在不同状态间的动态变化。我们将从基本概念开始,逐步学习如何建立和求解状态空间模型,特别是马尔可夫模型。

概述

状态空间建模将系统视为处于多个可能状态之一。系统会因各种事件(如故障、修复)在这些状态之间转移。通过量化这些转移的概率或速率,我们可以评估系统处于不同状态(如正常运行、性能降级、完全失效)的可能性,从而分析其可靠性、可用性和性能。

上一节我们介绍了组合建模,本节中我们来看看基于状态空间的动态建模方法。

什么是状态空间建模? 🤔

关于计算能力或资源的可用性,系统可以被视为处于几个可能状态之一。你可以根据需要定义任意多的状态,可以对不同状态做精细区分,也可以将多个状态合并。

例如,一个系统可以被粗略地表示为处于四种状态之一:优秀状态、良好状态、一般状态和糟糕状态。系统在任一时刻只处于其中一种状态。系统会因资源可用性和计算能力的变化,在各种事件的影响下从一个状态转移到另一个状态。

在容错计算中,例如发生故障时,系统可能从优秀状态转移到一般状态。这些转移通常有与之相关的概率。在离散时间模型中,转移用概率描述;在连续时间模型中,转移用速率描述。速率表示单位时间内发生转移的平均次数。

我们感兴趣的是找出系统处于最理想状态(以及其他状态)的概率,因为这有助于我们从概率意义上评估系统的可用性。

马尔可夫模型 ⛓️

我们讨论的起点是被称为马尔可夫链(或马尔可夫模型)的模型。马尔可夫模型由一组状态和状态间的转移概率(或速率)构成。

下图展示了一个四状态系统的离散时间马尔可夫模型。状态用数字0、1、2、3表示。转移概率构成了一个马尔可夫转移矩阵 M

状态转移矩阵 M 示例:
[ 0.3, 0.4, 0.3, 0.0 ]
[ 0.5, 0.4, 0.0, 0.1 ]
[ 0.0, 0.0, 1.0, 0.0 ]
[ 0.0, 0.0, 0.0, 1.0 ]

马尔可夫矩阵是一个方阵,其行数和列数等于状态数。关键特性是:矩阵中每一行的元素之和必须为1。这意味着系统在下一时刻要么保持在当前状态,要么转移到某个其他状态。

马尔可夫模型的一个优点是:如果你知道系统在时间 t 的状态(用一个概率向量 s(t) 表示),那么通过将状态向量乘以转移矩阵 M,就可以得到系统在时间 t+1 的状态:
s(t+1) = s(t) * M

经过 h 个时间步长后,状态为:
s(t+h) = s(t) * M^h
可以证明,马尔可夫矩阵的任意次幂仍然是一个马尔可夫矩阵。

马尔可夫链是随机时序机的一个特例,后者可能有多个与不同输入对应的转移矩阵。而马尔可夫链是自主的,没有外部输入。

马尔可夫模型的应用实例 💻

马尔可夫模型有广泛的应用。以下是一些例子:

  • 程序员活动模型:该模型描述了程序员在“构思问题”、“编写程序”、“编译程序”、“测试程序”、“调试”、“运行”和“优化”等状态间的活动。转移概率和平均耗时(延迟)是通过收集数据得到的。通过该模型,可以评估程序员在各个活动上花费的时间比例。
  • 计算机系统模型:这是我们课程关注的重点。例如,对于一个三处理器并行系统,可以定义8个状态,对应三个处理器不同组合的工作/故障情况(如111表示全正常,110表示前两个正常第三个故障)。如果处理器相同,且我们不关心具体哪个处理器故障,可以将“单故障”的三个状态合并为一个状态,从而简化为一个四状态模型(3个正常,2个正常,1个正常,0个正常)。转移速率通常包括故障率(λ)和修复率(μ)。模型的具体设置(如状态定义、转移速率)取决于系统设计和分析目标。

建立系统的马尔可夫模型并非易事,需要考虑许多问题:使用哪些状态、为转移分配何种速率等。

建立和求解马尔可夫模型 🛠️

让我们从简单系统开始,逐步建立更复杂的马尔可夫模型。

简单非可修复系统

考虑一个两状态系统:“运行”(状态1)和“失效”(状态0)。系统以故障率 λ 从状态1转移到状态0,且没有从状态0转出的转移(吸收态)。对于这种不可修复系统,长期运行后系统必定会进入失效状态。

通过建立微分方程可以求解瞬态概率:
p1'(t) = -λ * p1(t)
p0(t) = 1 - p1(t)
其中 p1(t) 是时刻 t 处于状态1的概率。求解得到:
p1(t) = e^{-λt} (即可靠度 R(t))
p0(t) = 1 - e^{-λt}

K-out-of-N 非可修复系统

系统由 N 个相同单元组成,至少需要 K 个正常才能工作。状态表示正常单元的数量(N, N-1, ..., K, F)。转移速率从状态 i 到 i-1 为 。状态 F 是吸收态。

通过建立一系列微分方程可以求解各状态瞬态概率。例如:
pN'(t) = -Nλ * pN(t)
p{N-1}'(t) = Nλ * pN(t) - (N-1)λ * p{N-1}(t)
... 依此类推,并结合总概率和为1的条件求解。

简单可修复系统

这是最基本的两状态可修复模型:状态1(运行),状态0(失效)。故障率 λ 使系统从1到0,修复率 μ 使系统从0到1。该系统没有吸收态,存在稳态。

稳态分析:通过建立平衡方程求解稳态概率。

  1. p1 + p0 = 1
  2. 对于状态1:离开的速率 = 进入的速率 => λ p1 = μ p0
    求解得稳态可用度 A 和不可用度 U
    p1 = μ / (λ + μ)
    p0 = λ / (λ + μ)
    通常 μ >> λ,因此稳态可用度接近1。

瞬态分析:通过求解微分方程组得到随时间变化的概率:
p1(t) = μ/(λ+μ) + [λ/(λ+μ)] * e^{-(λ+μ)t}
p0(t) = λ/(λ+μ) - [λ/(λ+μ)] * e^{-(λ+μ)t}
当 t=0 时,p1(0)=1;当 t→∞ 时,趋于稳态值。

更复杂的可修复系统模型

模型可以包含更多状态和转移,以区分不同类型的故障(如安全故障/非安全故障)、性能降级等级等。通过为每个状态建立平衡方程(离开速率=进入速率),并结合总概率和为1的条件,可以求解稳态概率。然后可以进行可靠性、安全性和性能度评估。

性能度评估示例:如果系统在状态2、1、0的性能水平分别为 b2, b1, b0,则系统性能度 P 为:
P = b2 * p2 + b1 * p1 + b0 * p0

覆盖因子建模:在故障处理中,可能无法完美地检测和恢复。覆盖因子 C 表示成功处理故障并进入降级运行状态的概率,而 (1-C) 则表示直接导致完全失效的概率。可以在转移中引入覆盖因子来建模这种不完美性。

求解瞬态概率:拉普拉斯变换法 📐

对于更复杂的模型,求解微分方程组以获得瞬态概率解析解可能需要使用拉普拉斯变换。基本步骤如下:

  1. 应用拉普拉斯变换:将时间域的微分方程组转换为复频域(s域)的代数方程组。拉普拉斯变换将导数 dx/dt 转换为 sX(s) - x(0),其中 X(s)x(t) 的变换,x(0) 是初始条件。
  2. 求解代数方程组:在 s 域中求解出 P1(s), P0(s) 等。
  3. 应用逆拉普拉斯变换:将 s 域的解答转换回时间域,得到 p1(t), p0(t)。通常需要将复杂的 s 域表达式分解为部分分式,以便利用已知的拉普拉斯变换对(如 1/(s+a) 对应 e^{-at})进行逆变换。

此方法虽然涉及数学技巧,但借助变换表和部分分式分解,可以系统化地求解线性常系数微分方程组。

生灭过程 🐣⚰️

生灭过程是一类特殊的马尔可夫模型,状态代表“种群”数量(如顾客数、故障部件数),转移只发生在相邻状态之间。“生”使数量加1(速率 λ_i),“灭”使数量减1(速率 μ_i)。

一个经典应用是排队论模型,如银行柜台服务。状态表示排队顾客数。顾客到达速率和服务速率决定了队列长度的概率分布。即使平均服务速率高于平均到达速率,由于随机性,队列仍可能形成并增长。

对于生灭过程,稳态概率 p_j 有通用表达式:
p_j = p_0 * (λ_0λ_1...λ_{j-1}) / (μ_1μ_2...μ_j)
其中 p_0 通过所有概率之和为1的条件确定。

此模型也可用于对多部件可修复系统进行建模,状态表示故障部件数量,转移速率与当前故障数相关。

三模冗余(TMR)系统示例 🔧

TMR系统使用三个相同模块,通过多数表决输出。其马尔可夫模型可包含状态:3个正常(全功能)、2个正常(容错运行)、失效。

  • 无修复的TMR:平均无故障时间(MTTF)甚至可能低于单模块系统,但其短期可靠性更高。
  • 带修复的TMR:在降级状态(2个正常)引入修复(速率 μ)将故障模块恢复,可以显著提高系统的MTTF。MTTF的公式包含一个因子 (1 + (μ/6λ)),由于 μ/λ 通常很大,因此MTTF得到极大改善。

可靠性建模流程与工具 🧰

可靠性建模是一个迭代过程:

  1. 选择建模方法(组合模型或状态空间模型)。
  2. 构建模型
  3. 确定模型参数
  4. 求解模型
  5. 解释结果
  6. 验证模型和结果
    如果结果不合理或验证失败,可能需要返回前面的步骤进行调整。

存在许多软件工具可辅助可靠性建模分析,例如:

  • 商业软件:PTC Windchill、Isograph等。
  • 学术机构提供的免费工具:如弗吉尼亚大学、爱荷华州立大学发布的工具。
  • 基于MATLAB的工具箱。
    这些工具可用于处理复杂模型,但在本课程中,我们主要关注原理和手工计算。

总结

本节课中我们一起学习了状态空间建模的核心内容。我们了解了如何将系统抽象为一系列状态,并使用马尔可夫模型描述状态间的随机转移。我们学习了如何为不同系统(非可修复、可修复、K-out-of-N、带覆盖因子、生灭过程、TMR等)建立模型,并通过平衡方程求解稳态概率,或通过微分方程和拉普拉斯变换求解瞬态概率。状态空间建模是一种强大的工具,使我们能够定量分析系统的可靠性、可用性、安全性和性能度,是容错计算领域的重要基础。

005:缺陷避免与防护

在本节课中,我们将学习教材的第5章和第7章,主要内容是缺陷避免以及屏蔽与加固技术。我们将探讨集成电路中常见的缺陷类型、如何通过设计和管理来避免它们,以及如何保护系统免受外部干扰和恶劣环境的影响。


缺陷避免

上一节我们概述了课程内容,本节中我们来看看缺陷避免的具体概念。缺陷是指在制造或使用过程中,系统中出现的不期望的物理瑕疵。这些瑕疵可能导致系统故障。

下图展示了集成电路中的两种缺陷:

  • 未填充的通孔(左图):通孔是连接不同金属层的孔洞。在制造过程中,如果金属未能完全填充孔洞,就会导致电气连接不良或完全失效。
  • 嵌入的颗粒(右图):在沉积电路层时,微小的颗粒可能嵌入层与层之间,导致该区域的连接或晶体管形成不良。

为了避免颗粒污染,集成电路在洁净室中制造。随着电路密度增加,特征尺寸变小,颗粒和制造工艺微小变化的影响变得更加显著。

制造工艺变化与高温问题

除了颗粒,制造工艺的微小变化也会导致缺陷。例如,导线形状的微小差异可能导致意外的短路(桥接)或断路。此外,集成电路运行时会产生热量,形成局部热点。过高的温度可能导致器件烧毁。

为了避免高温问题,可以采取以下措施:

  • 在多核芯片上重新分配计算负载。
  • 监控芯片温度。
  • 在极端情况下,关闭芯片让其冷却。

时钟信号与磁盘缺陷

我们通常将时钟脉冲想象为完美的方波,但实际的高频时钟信号边沿是倾斜的,并且脉冲之间可能存在变化。电路设计必须能够容忍这些时钟抖动

缺陷也存在于集成电路之外。例如,在磁盘存储器中:

  • 盘片表面的划痕可能损坏数千个数据位。
  • 读写磁头与盘片表面的距离极其微小,灰尘、指纹甚至烟雾颗粒都显得过大,可能造成损坏。

现代磁盘被密封在腔体内,并且磁头利用空气轴承悬浮在盘片上方,以适应盘片旋转时的微小摆动。

磁盘错误处理与预警

为了处理磁盘表面的缺陷(如制造时产生的划痕),采用了多级编码和重映射技术。

以下是磁盘数据组织的示意图:

  • 扇区级编码:每个扇区包含数据和一些冗余校验位,可以检测和纠正少量错误。
  • 块级编码:多个扇区组成一个块,拥有额外的纠错能力。
  • 超级块级编码:提供更高层的保护。

如果某个扇区损坏过于严重无法纠正,磁盘系统会将其重映射到一个完好的备用物理区域。操作系统访问的逻辑地址保持不变,但磁盘内部的物理地址已经改变。

磁盘驱动器最终会失效。通过监控运行状态,可以在完全故障前发现预警迹象,进行预防性更换。常见的预警信号包括:

  • 磁头飞行高度持续降低。
  • 重映射扇区的数量异常增加。
  • 纠错码被频繁触发的次数增多。

成品率与缺陷建模

上一节我们讨论了具体的缺陷案例,本节我们来分析制造中的宏观指标——成品率。成品率是衡量制造过程质量的关键,直接影响芯片成本。

典型的集成电路制造流程如下:硅锭被切片成晶圆,在晶圆上制造多个芯片(称为“晶粒”或“管芯”),然后进行切割和测试。晶圆上的缺陷点会导致其覆盖的晶粒失效。

成品率 定义为合格晶粒数量与总晶粒数量的比值。晶粒面积越大,单个晶粒包含缺陷点的概率就越高,因此成品率越低。成品率 Y 可以通过以下经验公式估算:

Y = (Wafer Yield) * (1 + (Defect Density * Die Area) / α)^-β

其中:

  • Defect Density 是缺陷密度。
  • Die Area 是晶粒面积。
  • αβ 是与制造工艺相关的常数(通常 β 在3到4之间)。

晶粒成本 可以用以下公式近似表示:

Die Cost ≈ Cost of Wafer / (Number of Dies per Wafer * Die Yield)

低成品率不仅会提高单个芯片的成本,还对测试提出了极高要求。例如,假设成品率为50%,要保证出厂产品的缺陷率低于100ppm(百万分之一百),就必须通过测试筛除掉99.99%的缺陷芯片,这需要极其昂贵和耗时的测试方案。

缺陷建模

由于缺陷微小且不规则,我们通过建模来预测其影响。缺陷通常分为:

  • 全局缺陷:影响大片区域,如划痕、掩模版错位。
  • 局部缺陷:局限于小区域,如因工艺问题导致的材料多余或缺失。

在模型中,复杂的缺陷形状常被简化为圆形。通过计算缺陷圆形与电路关键区域(如两条导线之间的间隙)的重叠概率,可以估算出导致故障的“致命缺陷”数量。

缺陷的尺寸分布符合一定的规律,小尺寸缺陷比大尺寸缺陷更常见。分布函数通常为:

f(x) = k / x^p

其中 x 是缺陷尺寸,p 是一个常数(通常约为3),k 是归一化常数。


浴盆曲线与老化测试

产品的故障率随时间变化的曲线形状类似浴盆,故称浴盆曲线

它包含三个阶段:

  1. 早期失效期:故障率较高,通常由潜在缺陷导致。
  2. 偶然失效期:故障率低且相对稳定,是产品的正常使用寿命期。
  3. 耗损失效期:故障率因老化磨损而再次上升。

对于电子产品,我们主要关注前两个阶段。为了不让客户经历早期失效,制造商会进行老化测试。由于正常使用下早期失效期可能长达数月,因此采用加速应力测试(如高温、高电压运行)在几小时或几天内激发潜在缺陷,筛除不良产品。


屏蔽与加固

上一节我们介绍了如何避免制造缺陷,本节我们来看看如何保护系统免受外部环境的影响。屏蔽与加固技术用于防止外部干扰或抵御恶劣工作条件。

串扰

串扰是指一个电路或信道中的信号对另一个电路或信道产生不良影响的现象。在高速高密度集成电路中,相邻导线之间的寄生电容电感耦合是串扰的主要原因。

  • 攻击线:产生干扰的信号线。
  • 受害线:受到干扰的信号线。

随着导线间距缩小、高度增加,它们之间的耦合电容增大,串扰问题加剧。缓解方法包括:

  • 增加导线间距。
  • 采用类似双绞线的交错布线技术,使干扰在不同区段相互抵消。

屏蔽

屏蔽是使用特殊封装或覆盖层来保护电路免受外部干扰。

  • 静电屏蔽袋:防止运输中的静电放电损坏电路。
  • 金属屏蔽壳:用于航天计算机,防护宇宙射线。
  • 射频屏蔽罩:阻止外部无线电频率干扰。

辐射效应与加固

辐射(如宇宙射线、α粒子、中子)对现代高密度集成电路构成威胁。高能粒子撞击芯片可能产生电子-空穴对,导致局部电流脉冲,进而引发瞬态错误或永久性损伤。

辐射效应包括:

  • 单粒子翻转:改变存储器或寄存器的状态。
  • 单粒子瞬态:产生一个可能被后续电路锁存的虚假脉冲信号。
  • 单粒子烧毁:导致永久性物理损坏。

辐射加固可以通过以下方式实现:

  • 使用更耐辐射的宽禁带半导体材料(如碳化硅)。
  • 采用屏蔽封装。
  • 用更坚固的SRAM替代DRAM。
  • 在电路级采用冗余设计(如三模冗余)。
  • 在更高层级采用故障检测与容错算法。

不同类型的辐射需要不同厚度的屏蔽材料。例如,阻挡电子相对容易,而阻挡质子则需要厚得多的屏蔽层。

其他环境因素

系统还可能受到振动、冲击和液体泼溅的影响。商用产品(如手机、笔记本电脑)已具备一定的耐受性。对于更严苛的环境(如工业、航天),则需要使用专门的加固型设备,它们通常更重、更昂贵,但能承受更强的振动、冲击并具备防溅洒能力。


总结

在本节课中,我们一起学习了缺陷避免屏蔽加固的核心内容。

我们首先探讨了集成电路中缺陷的来源和影响,包括工艺变化、颗粒污染和高温问题,并介绍了磁盘存储器的缺陷处理机制和预警更换策略。

接着,我们分析了成品率对芯片成本和测试的深远影响,并了解了如何使用缺陷模型来预测制造质量。浴盆曲线老化测试帮助我们理解产品寿命并剔除早期失效品。

最后,我们转向外部威胁,学习了串扰的成因与缓解方法,以及如何通过屏蔽辐射加固技术保护电子系统。我们还简要提及了系统对振动、冲击等机械和环境压力的耐受性设计。

通过结合缺陷避免和系统加固,我们可以从设计和制造层面显著提升计算系统的可靠性和鲁棒性。

006:缺陷规避 🛡️

在本节课中,我们将要学习缺陷规避的基本概念、通用方法以及一些具体实例。缺陷规避的核心思想是检测缺陷,并通过移除或屏蔽的方式,来规避其不良影响。

缺陷规避的两种互补方法

上一节我们介绍了缺陷规避的目标,本节中我们来看看实现这一目标的两种主要方法。它们是互补的,可以在特定场景中单独或组合使用。

缺陷规避通过移除
此方法要求系统具备动态冗余。它需要在晶圆或芯片层面识别出缺陷部件。识别方式可以是目视检查(针对大缺陷)或测试与关联分析。关联分析类似于通过症状诊断疾病,即通过观察与缺陷相关的效应来推断缺陷的存在。随后,系统通过内置的嵌入式开关来绕过缺陷或重新配置系统。

缺陷规避通过屏蔽
此方法要求提供所谓的静态冗余。静态冗余是指冗余结构内建于系统中,并作为系统正常操作的一部分。当出现问题时,这些内置的冗余会自动生效,防止不良后果发生。

可以这样类比:缺陷移除类似于错误检测码,你检测到问题,但需要采取行动来纠正或移除错误的影响。而缺陷屏蔽则类似于错误纠正码,冗余是内置的,它能自动纠正错误,通常不涉及系统重配置。

一般来说,静态冗余需要更高程度的冗余,因此在电路成本和功耗方面更昂贵。有时我们会在检测到缺陷后对冗余结构进行调整,但这是可选的,并非必需。因为存在足够的冗余来抵消缺陷部分的影响,系统可以继续运行。

鉴于缺陷移除意味着较低的冗余度,从而带来更低的电路成本和能耗,这些方法在集成电路中更受欢迎。

缺陷检测方法

以下是缺陷检测的几种方式:

  • 目视或光学检查:在晶圆制造完成后,由专家进行检查,重点关注更可能出现缺陷的区域(如晶圆边缘)。严重的大缺陷可以通过目视发现。也可以使用光学检查,通过分析光线照射晶圆后的反射情况来判断是否符合预期,这通常能更准确地捕捉到微小缺陷。
  • 测试与关联分析:通过运行测试并观察异常效应(症状)来推断缺陷的存在。

适用于芯片冗余与重配置的系统

在芯片上使用冗余和重配置技术,在系统具有规则结构时效果最佳。

这类系统的例子包括:

  • 存储器
  • 现场可编程门阵列
  • 多核芯片芯片多处理器

对于不规则或随机逻辑,则需要更高程度的冗余,因为除了复制结构外没有太多选择。在复制时,需要确保复制单元在芯片上不要靠得太近,以免芯片某一区域的单个缺陷同时影响原始单元和复制版本。另一方面,如果将这些单元在芯片上放置得太远,当需要替换故障单元时,布线和开关开销会变得非常大。因此,需要在“足够远以避免单点缺陷影响多个单元”和“足够近以控制开关和布线成本”之间取得平衡。

磁盘存储中的坏扇区规避

避免使用磁盘存储器上的坏扇区,是“通过移除实现缺陷规避”的一个典型例子。

磁盘使用非常强大的错误纠正码,实际上是纠错码和检错码的组合。当我们通过这些码发现磁盘上某个特定扇区(存储信息块的一个区域)是坏的时,就不再向该扇区记录数据,因为获取错误数据的概率会很高。我们通过重映射将该扇区映射到磁盘的不同区域。

逻辑地址(如“扇区A”)和物理地址是分离的,因此通过重定位扇区,我们可以规避坏扇区的影响。

在此机制中,涉及两种映射表:

  • P表(主缺陷表):由磁盘制造商建立。在制造和测试过程中发现某些扇区不可靠后,制造商会直接绕过这些扇区,并建立一个映射表指明这些扇区的新位置。P表不影响磁盘的标称容量和性能,因为制造商会将磁盘做得略大一些,并在重映射后仍能保证标称规格。
  • G表(增长缺陷表):在磁盘出厂后,由磁盘驱动软件检测到坏扇区时建立。例如,当某个扇区读取时纠错码频繁介入,就认为该扇区可能不再可靠,从而将其重映射。随着G表增长,磁盘的实际可用容量会减少,性能也可能受影响(因为文件可能被存储在不连续的物理位置)。当G表变得过大时,可能需要更换磁盘。

存储器阵列的缺陷规避

多年来,针对存储器阵列开发了许多缺陷规避技术。

一种常见的方法是为存储器阵列提供备用行(通常还有备用列)。假设一个存储器阵列的某一行出现缺陷(整行或部分存储单元),我们没有能力替换单个存储单元,因此需要替换包含缺陷的整行。

这是通过解码机制实现的。通常,解码器根据地址选择某一行(例如第100行)。如果该行有缺陷,则必须将逻辑上的第100行映射到一个备用行。因此,解码逻辑必须具备这种映射能力,比普通解码器更复杂。

假设有 M 行主存储器和 S 个备用行,并且假设所有外围逻辑和解码器完全可靠(简化假设),那么只要 M+S 行中有任意 M 行是好的,系统就是好的。这可以建模为一个 M out of M+S 系统。如果考虑外围逻辑的失效率,只需将其与此系统的可靠性相乘即可。

如果同时提供备用列,则可以替换故障列。注意,如果整列失效,备用行作用有限,因为失效单元数量多。备用列对于沿列方向聚集的缺陷更有效,而备用行对于沿行方向聚集的缺陷更有效。

逻辑电路中的缺陷规避

在逻辑电路中规避缺陷影响有很长的历史。早在1950年代,Moore和Shannon就提出了开创性的想法,即用高度不可靠的“劣质”继电器构建任意可靠的继电器电路。

其工作原理如下:假设一个继电器在应该断开时错误闭合的概率是 P(缺陷概率)。现在,我们使用四个继电器组成一个冗余结构,而不是单个继电器。所有继电器由同一个信号 X 控制。

当 X=0(期望电路断开)时,所有四个继电器都应断开。如果其中一个继电器有缺陷而闭合,电流仍然无法从左流到右,因为其他三个继电器是断开的。然而,如果两个继电器同时有缺陷并闭合(有四种可能的组合),则电路可能错误导通。

可以计算出这个冗余继电器电路的整体错误闭合概率 H(P) 为:
H(P) = 4p^3 - 3p^4
(注:原文公式推导有误,此处根据上下文修正为常见可靠度计算公式,对于2-out-of-4系统,失效概率为 C(4,3)p^3(1-p) + C(4,4)p^4 = 4p^3 - 3p^4,故 H(P) 应为此值)

如果 H(P) < P,即该结构误操作的概率小于单个继电器的误操作概率,那么就可以递归地使用此方法,将可靠性提高到任意所需水平。对于这个特定结构,当 P < 0.5 时,H(P) < P 成立(原文为0.382,但根据常见计算,阈值应为0.5)。如果 P 非常小,该结构将足够可靠。

虽然继电器是旧技术,但CMOS传输晶体管这类开关在IC中很常见,因此这些方法再次变得适用,例如在FPGA中。

FPGA天生适合缺陷规避。如果某个逻辑块被发现有缺陷,只需声明其不可用。将设计映射到FPGA的工具通常具备避开特定逻辑块或互连线的能力。这是内建于设计工具中的功能。

FPGA中的可编程开关盒允许在水平和垂直通道之间建立灵活连接。如果某个通道有缺陷,可以通过设置开关状态来避免使用它。

多核芯片的缺陷规避

多核芯片也具有天然的绕过或规避能力。例如,要制造一个八核芯片,通常会构建比需求更多的核心(例如10个)。如果在测试中发现一两个核心有缺陷,只需不使用它们。如果核心通过总线连接,隔离这些故障单元即可。如果是更复杂的互连网络,则需要设计网络,使其在特定端口失效时仍能允许其他核心灵活通信。

一种组织芯片上多个处理单元的方法是构建为一维或二维阵列。

  • 一维阵列:每个单元是独立的,有自己的I/O连接。但这可能导致芯片引脚数成为瓶颈。
  • 二维阵列:减少了每个处理器的I/O引脚需求,但灵活性降低。如果阵列中某个处理器失效,需要提前设计互连,确保其他处理器仍能有效工作。

一种策略是构建比需求更大的阵列(包含备用行和列),并通过提供备用连接来重配置芯片,避开缺陷区域,从而“挽救”出一个功能正常的子阵列。这需要设计允许行和列“移位”的开关结构。

重配置方案详述

为了实现上述规避,需要使用可配置的开关。例如,四端口开关可以有两种状态:“弯曲”状态和“交叉”状态。

利用这种开关,可以构建一维阵列,并通过设置开关状态来旁路故障处理器单元。这种方案的可靠性建模为:处理器部分是一个 4 out of 5 系统(如果能容忍1个缺陷),与开关系统串联。开关通常比处理器简单,因此对整体可靠性影响较小。

为了减少作为系统“硬核”(必须正常工作的部分)的开关数量,可以采用分布式重配置方案。在每个处理器单元内部集成多路复用器,使其可以选择输入来源。这样,硬核就减少到只剩下这些多路复用器,开关缺陷的影响不再比处理器缺陷更严重。

对于二维处理器阵列,也有集中式和分布式的重配置方案。分布式方案在每个处理单元提供多路复用器,以选择其北向和西向邻居的来源,从而避免开关成为单一的故障点。

基于备用行/列的二维重配置

假设我们有一个需要 N x N 的处理器阵列,我们构建一个带有 R 个备用行和 C 个备用列的更大阵列。如果存在缺陷处理器,我们可以通过“移动”行和列来避开它们,利用备用行/列来填补位置,最终形成一个无缺陷的 N x N 逻辑阵列。

该方案的一个关键特性是:只要能够从备用行或备用列向每个缺陷处理器画出一条箭头(表示替换路径),并且这些箭头互不相交,那么系统就是可重配置的。最坏情况下,仅需三个特定位置分布的缺陷就足以使该(单备用行、单备用列)方案失效。因此,在可靠性建模中,对于 N x N 阵列,可以将其建模为 N² - 2 out of N² 系统(即最多容忍2个缺陷)。这是一个悲观的、保证的下界。实际中,由于缺陷分布随机,通常可以容忍更多缺陷。

可以在阵列的上下左右都放置备用行/列,以提供更大的灵活性(允许上下左右移位),从而容忍更多缺陷。

成品率提升

许多缺陷规避方案源于提高集成电路成品率的努力。通过在芯片上提供冗余元件,即使存在缺陷,我们仍然可以使用该芯片,从而提高成品率。

成品率模型通常将缺陷建模为圆形,尽管实际缺陷很少是圆形的。只要模型的预测结果与现实匹配,它就是有用的模型。

一个简单的例子:假设有一个1平方厘米的芯片,上面只有宽度和间距均为1微米的导线。平均缺陷密度为每平方厘米10个随机缺陷。进一步假设80%的缺陷是小缺陷(直径0.5微米),不会导致导线短路;20%的缺陷是大缺陷(直径1.5微米)。大缺陷只有当其中心落在特定的“关键区域”(约占芯片面积的四分之一)时才会导致短路。通过概率计算,可以估算出该芯片的成品率。这个例子展示了建模的基本思路,实际中缺陷尺寸分布更复杂,但可通过计算机化模型处理。

冗余是提升成品率的方法,但仅提供冗余元件并不足够,还需要考虑如何用冗余单元替换故障单元以及相关的互连问题。通常,将单元组织成行和列,并用备用行/列替换整行/整列,可以使重配置变得简单,但可能造成浪费。

在VLSI布局布线中,必须考虑缺陷的影响。较宽的导线对材料缺失缺陷不敏感(更难断开),但更容易因多余材料缺陷导致桥接。较窄的导线则相反。因此,需要在导线宽度和间距之间进行权衡,以最小化各类“致命缺陷”的概率。

存储器成品率提升实例

为了提高存储器成品率,我们提供备用行和列。这是一个覆盖问题,在一般情况下是NP完全的。

可以将问题转化为二分图模型:一侧节点代表行,另一侧节点代表列。如果第 i 行第 j 列有一个缺陷单元,则在代表第 i 行的节点和代表第 j 列的节点之间连一条边。选择备用行和备用列来替换,等价于在二分图中选择一组行节点和列节点,使得这些选中的节点“覆盖”了所有的边(即每条边至少与一个选中的节点相连)。

对于随机缺陷,R 个备用行和 C 个备用列保证可以规避最多 R x C 个缺陷(在最坏情况下,每个缺陷都在不同的行和列)。实际上,缺陷往往在行或列上聚集,因此通常可以规避比 R x C 更多的缺陷。

组合多种冗余方案

通常,我们会组合使用多种冗余方案,以发挥每种方案的优势。一个经典例子是同时使用纠错码备用行/列

  • 纠错码擅长处理孤立的、随机的缺陷(例如,单错纠正码可以纠正一个缺陷单元的影响)。
  • 备用行/列擅长处理聚集的缺陷(例如,一整行或列的失效)。

研究表明,单独使用纠错码或备用行/列时,芯片在成品率下降到不可接受水平前所能容忍的平均缺陷数量有限。而将两者结合使用,则可以容忍多得多的缺陷,从而显著提高成品率。当然,组合方案也需注意各自的缺点。

回顾与前瞻

我们已经完成了对“缺陷”状态及其处理方法的探讨。我们讨论了老化测试,它暴露潜在缺陷并将其转化为故障。虽然我们致力于使系统向更好的状态转变(向上转换),但有时我们故意让系统经历向下转换(如老化测试、故障测试),因为故障比缺陷更容易观察,错误比故障更容易观察。通过在这些条件下测试,我们可以检测到缺陷或故障的存在。

下一次课程,我们将讨论故障层面的内容:故障检测与测试,以及可测试性设计。故障容错是我们在本课所学的缺陷容错在故障层面的对应概念。


本节课中我们一起学习了缺陷规避的核心概念,包括通过移除和屏蔽两种基本方法,以及在存储器、逻辑电路、FPGA、多核芯片和磁盘等具体系统中的应用实例。我们还探讨了如何通过冗余和重配置技术来提升系统可靠性与成品率,并了解了组合多种方案的优势。理解这些基础方法,是构建更健壮、更可靠计算系统的重要一步。

007:故障检测与可测试性设计

在本节课中,我们将学习故障检测的基本概念、方法以及如何设计易于测试的电路。课程内容涵盖教材的第9章(故障测试)和第11章(可测试性设计)。

概述

故障测试旨在通过强制电路中的逻辑故障产生可观测的错误,从而检测故障的存在。与之相对的故障掩蔽,则旨在防止系统从故障状态进入错误状态。本讲将重点讨论故障测试,特别是结构测试方法,并介绍如何通过设计提高电路的可测试性。

故障测试简介

故障测试的过程通常包括三个部分:测试生成、测试验证和测试应用。

上一节我们介绍了故障测试的基本目标,本节中我们来看看测试过程的三个核心环节。

以下是测试过程的三个主要部分:

  • 测试生成:确定用于检测故障的输入模式。可以是预设的,也可以是自适应的。
  • 测试验证:通过理论证明或实验(如仿真、故障注入)来确认测试的有效性。
  • 测试应用:将测试模式施加到被测电路上,可以是外部控制(如自动测试设备ATE),也可以是内部控制(如内建自测试BIST)。

结构测试与故障模型

由于功能测试(将电路视为黑盒)通常不切实际(例如,测试一个32位加法器需要2^64个输入模式),我们更常使用结构测试。结构测试基于对电路内部结构的了解来生成测试。

为了进行结构测试,我们需要从故障模型开始。

以下是结构测试的几个关键概念:

  • 故障模型:定义电路中可能出错的类型。在门级,最常用的模型是固定型故障,即某条信号线永久固定为逻辑0(stuck-at-0)或逻辑1(stuck-at-1)。
  • 故障覆盖率:目标检测的故障比例(例如99%)。
  • 诊断程度:目标是仅判断电路好坏(go/no-go测试),还是精确定位故障位置。

D算法:一个测试生成示例

D算法是一种经典的结构测试生成算法。其核心思想是通过反向追踪确定能激活故障(例如,迫使某条stuck-at-0的线呈现逻辑1)的输入值,并通过前向追踪路径敏化,将故障效应(用D表示正常值为1/故障值为0,表示正常值为0/故障值为1)传播到可观测的输出端。

考虑一个简单电路,我们想检测图中P点stuck-at-0的故障。

  1. 激活故障:要使P点在正常电路中的值为1,需要A和B不同(即A=0,B=1或A=1,B=0)。此时,正常电路P=1,故障电路P=0,该点信号值为D
  2. 传播故障效应:为了将D传播到输出K,需要设置C=1(使与门另一输入为1),并设置其他输入使或门的另一输入为0(该条件已由步骤1满足)。
  3. 确定测试向量:因此,能检测P点stuck-at-0的测试输入为(A,B,C) = (0,1,1)(1,0,1)

对所有关心的故障(每条线的stuck-at-0stuck-at-1)重复此过程,可以生成一个测试表,然后通过优化选取最少的测试向量集合来覆盖所有目标故障。

布尔差分法

布尔差分法提供了另一种理解测试生成的视角。它将检测特定故障的问题转化为一个逻辑等式可满足性问题。

函数K对变量B的布尔差分定义为:
∂K/∂B = K(B=0) ⊕ K(B=1)
∂K/∂B = 1时,表示K的值对B的变化敏感。

对于电路中某个因故障而变成独立变量的点P,要检测其stuck-at-0故障,需要找到满足以下等式的输入:
P · (∂K/∂P) = 1
其中,P=1用于激活故障,∂K/∂P=1用于将故障效应传播到输出。求解此等式即可得到测试向量。

可测试性设计

如果测试本身很困难,那么在设计电路时就应该考虑其可测试性。可测试性主要取决于两个因素:可控性可观测性

上一节我们了解了生成测试向量的算法,本节中我们来看看如何通过设计让测试变得更容易。

  • 可控性:从原始输入端控制电路内部某个节点难易程度的度量。
  • 可观测性:从原始输出端观测电路内部某个节点难易程度的度量。

可控性与可观测性的量化

我们可以为电路中的每条线分配一个介于0(不可控/不可观测)到1(完全可控/可观测)之间的数值。

可控性计算(前向传播)

  1. 所有原始输入的可控性设为1。
  2. 对于门电路,其输出可控性 = (输入可控性的平均值) × (该门的可控性传递因子)。
  3. 可控性传递因子计算公式为:1 - |#(输出为0的输入模式) - #(输出为1的输入模式)| / #(所有输入模式)
    • 例如,三输入与门有8种输入组合,7种使输出为0,1种使输出为1。其传递因子 = 1 - |7-1|/(7+1) = 1 - 6/8 = 0.25
    • 异或门(XOR)则具有很好的传递因子1。

可观测性计算(后向传播)

  1. 所有原始输出的可观测性设为1。
  2. 对于门电路的某个输入,其可观测性 = (输出可观测性) × (该输入到输出的可观测性传递因子)。
  3. 可观测性传递因子 = #(能敏化该路径的输入模式) / #(所有输入模式)
    • 例如,对于三输入与门,要敏化顶部输入到输出的路径,需要另外两个输入均为1,只有1/4的组合满足,因此传递因子为0.25。

可测试性 被定义为该点可控性与可观测性的乘积:Testability = Controllability × Observability。数值越低,表示该点越难测试。

提高可测试性的技术

如果电路中某点的可测试性很低,可以通过插入测试点来改善。

  • 控制点:插入一个多路选择器,在测试模式下可以从外部直接注入信号,提高可控性。
  • 观测点:插入一个缓冲器,将内部信号直接引到外部引脚,提高可观测性。

对于时序电路,其测试比组合电路困难得多,因为内部状态(触发器内容)难以控制和观测。扫描设计是解决此问题的关键技术。

以下是扫描设计的基本原理:

  • 将电路中的触发器连接成一个或多个扫描链
  • 在正常模式下,触发器正常工作。
  • 在测试模式下,触发器构成一个移位寄存器。我们可以通过扫描输入端口将任意测试向量串行移入(设置电路状态),执行测试后,再将结果状态通过扫描输出端口移出观察。
  • 这样可以显著提高时序电路内部状态的可控性和可观测性。局部扫描内建自测试是此技术的进一步发展和应用。

总结

本节课我们一起学习了故障检测与可测试性设计。我们首先介绍了故障测试的基本流程和结构测试方法,并详细讲解了D算法和布尔差分法这两种测试生成技术。我们了解到故障测试是一个NP难问题,需要启发式方法。接着,我们探讨了如何通过量化可控性和可观测性来评估电路的可测试性,并介绍了插入测试点、扫描设计等提高可测试性的关键技术。良好的可测试性设计能显著降低产品生命周期各阶段的测试成本与难度。在下一讲中,我们将学习故障掩蔽技术。

008:故障屏蔽与表决方案 🛡️

在本节课中,我们将学习教材第10章和第12章的内容。第10章主要讨论故障屏蔽的基本概念,而第12章则深入探讨实现故障屏蔽的一些具体技术,特别是各种表决方案。我们将从故障屏蔽与故障避免的对比开始,逐步介绍多种冗余技术及其应用。

故障屏蔽与故障避免的对称性 🔄

上一节我们介绍了课程概述,本节中我们来看看故障屏蔽与故障避免方法之间的对称关系。下图展示了这种对称性:左侧是故障避免方法,右侧是故障屏蔽方法。

故障避免可以通过两种方式实现:

  • 质量保证:预防故障的发生,使系统从一开始就是完美的。
  • 故障移除:通过测试来发现故障。测试后有两种可能:未检测到故障(系统仍存在故障),或检测到故障。检测到故障后,可以选择修复故障(完全修复或部分修复)或直接丢弃整个电路。

故障屏蔽则可以通过两种冗余方式实现:

  • 静态冗余:将故障隐藏起来,使其不影响系统运行。
  • 动态冗余:通过监控来暴露故障。监控后有两种可能:未检测到故障(系统仍存在故障),或检测到故障。检测到故障后,可以选择中止计算(使系统处于故障但安全的状态),或对系统进行重构(完全恢复或部分降级运行)。

这个图表完全对称地展示了左右两侧方法之间的对应关系。

交织冗余逻辑 🧩

上一节我们了解了故障屏蔽的整体框架,本节中我们来看看一种具体的实现思想——交织冗余逻辑。这个想法源于20世纪60年代,当时硬件昂贵,因此它更像一种理论探索。如今,随着纳米电子技术的发展,我们可以承受较高的冗余度,这种方法重新受到关注。

其核心思想是利用逻辑门固有的容错能力。即使在一个非冗余电路中,某些故障也可能被“掩盖”。例如,对于一个特定的输入组合,某个信号线的固定型故障可能不会影响最终输出的正确性,这种故障被称为非关键故障亚临界故障。相反,那些会影响输出的故障则称为关键故障

那么,能否利用这种固有特性来实现通用的故障屏蔽呢?答案是肯定的,这就是四倍逻辑 的思想。

在四倍逻辑中:

  • 原始电路中的每个门被四个相同的门替代。
  • 每个门的输入数量翻倍。
  • 每个信号也有四个副本。

在正常条件下,同一信号的四个副本具有相同的值。其工作原理依赖于电路中间层与或门的交替结构:一个关键故障(如与门输入从1变为0)在下一层的或门中会变成亚临界故障,从而被屏蔽。

更一般地,对于冗余度级别 h,门数量将乘以 (h+1)^2,门输入数量将乘以 (h+1)。当 h=1 时,就是四倍逻辑(4倍门,2倍输入)。当 h=2 时,则需要9倍的门和3倍的输入。

这种方法之所以称为“交织”,是因为信号副本以特定模式连接,例如将信号A的副本A1、A2与信号B的副本B1、B2组合输入到不同的门中,这种交叉连接对实现屏蔽功能至关重要。

摩尔-香农高可靠性继电器电路 ⚙️

上一节我们介绍了一种利用逻辑结构的屏蔽方法,本节中我们来看一个更早的经典思想——使用低可靠性元件构建高可靠性系统。这个由摩尔和香农在20世纪50年代提出的想法,旨在用质量很差的继电器构建高可靠的继电器电路。

继电器有两种类型:

  • 常开继电器:通电时闭合。
  • 常闭继电器:通电时断开。

定义两个概率:

  • a:继电器通电时触点闭合的概率。
  • c:继电器未通电时触点闭合的概率。

对于一个可靠的常开继电器,a 应远大于 c;对于一个可靠的常闭继电器,a 应远小于 c

摩尔和香农的核心思想是:即使继电器的 ac 非常接近(即继电器质量很差),只要 a 略大于 c(对于常开触点),就可以通过将多个继电器以冗余的串并联结构互连,达到任意高的可靠性。

例如,一个由四个继电器组成的桥式结构,其通电时连接成功的概率为 2a^2 - a^4。只要单个继电器的可靠性 a > 0.62,这个组合结构的可靠性就高于单个继电器。通过递归地应用这种结构,可以构建出可靠性越来越高的电路。

同时,该结构在未通电时形成连接(这是不希望的)的概率为 2c^2 - c^4,这个值被证明总是小于 c,即不可靠性总是降低的。

三模冗余与表决 🤝

上一节我们学习了用低可靠性元件构建高可靠系统,本节中我们来看当今最常用、最实用的故障屏蔽技术——三模冗余与表决。

基本结构是:使用三个相同的单元来计算同一个逻辑功能,然后通过一个表决器输出多数结果。

         +---+       +---+
输入 --->|单元1|----->|   |
         +---+       |   |
                     |   |
         +---+       |表决|---> 输出
输入 --->|单元2|----->|器  |
         +---+       |   |
                     |   |
         +---+       |   |
输入 --->|单元3|----->|   |
         +---+       +---+

只要三个单元中有两个工作正常,表决器就能输出正确结果,从而屏蔽掉一个故障单元。这里假设表决器本身是完美的。

三模冗余系统的可靠性 R_TMR 与单个模块可靠性 R_m 的关系为:

R_TMR = 3 * R_m^2 - 2 * R_m^3

R_m > 0.5 时,R_TMR > R_m,即系统可靠性得到提升。在实际中,模块可靠性通常远高于0.5,因此TMR能显著提高短期可靠性。

然而,从长期运行的平均无故障时间来看,TMR系统(5/(6λ))可能低于单模块系统(1/λ)。这再次说明,平均无故障时间并非比较系统可靠性的完美指标。

三模冗余的一个实际应用是抗辐射触发器设计。通过三倍化触发器并使用表决器,可以防止单粒子效应翻转存储的值。为了同时保护表决器本身,可以对表决器也进行三倍化。

冗余技术的扩展与对比 📊

上一节我们深入探讨了三模冗余,本节中我们将其扩展并与其他冗余技术进行对比。

我们可以将三模冗余推广到 N模冗余。使用 N 个模块和一个表决器,可以屏蔽 ⌊(N-1)/2⌋ 个故障。N 通常为奇数,但也可以是偶数(如四模冗余可以屏蔽一个故障,同时检测两个故障)。

以下是几种主要冗余技术的总结与对比:

动态冗余(例如:单工+热备)

  • 优点:功耗较低;通过备用模块可提供较长寿命。
  • 缺点:故障检测和切换可能不完美(覆盖问题);从故障发生到系统恢复存在延迟。

静态冗余(例如:TMR)

  • 优点:故障被立即屏蔽,安全性高。
  • 缺点:功耗和面积开销大;表决器成为关键单点。

混合冗余(例如:TMR+热备)

  • 优点:兼具立即屏蔽和长寿命的优点;安全性高。
  • 缺点:兼具前两者的缺点,如功耗高;开关和表决器组成的核心部分更复杂,是关键点。

在混合冗余中,备用模块的状态可以是:

  • 冷备:断电状态,接入需要较长时间。
  • 热备:与主模块同步运行,可快速接入。
  • 温备:介于两者之间,已加电但可能需要初始化。

时间冗余与测试性设计 ⏱️

上一节我们比较了空间上的冗余技术,本节中我们来看看另一种思路——时间冗余,并讨论冗余系统的测试问题。

时间冗余 是指使用同一硬件单元在不同时间多次执行同一计算,然后比较结果。这对于屏蔽瞬态故障特别有效。为了也能检测某些永久性故障,可以采用操作数变换技术,例如:

  • 在加法中交换操作数顺序。
  • 使用补码运算:先计算操作数的反码,相加后再对结果取反。
  • 在乘法中,如果操作数是偶数,可以将其除以2,另一个操作数乘以2,从而改变流经电路的数据路径。

冗余系统的测试 面临挑战。例如,一个已部署的三模冗余系统,如果其中一个模块在仓库中已失效,常规测试可能无法发现,因为表决器会屏蔽这个故障。这样,系统在交付时已带有一个潜在故障,容错能力下降。

为了提高测试性,可以增加测试结构,例如使用多路选择器将每个模块的输出单独引出观测,从而在测试时绕过表决器,直接检测每个模块的健康状态。

表决器设计详解 🎛️

上一节我们提到了表决器是关键部件,本节中我们深入探讨表决器的不同设计方法及其复杂度。

表决器的输入可以是单比特,也可以是字(多位)。对于单比特输入,设计相对直接。以下是几种设计方法:

  1. 基于门电路的设计:复杂度随输入数 n 呈指数增长,不适合大规模输入。
  2. 基于多路选择器的设计:例如三输入表决器可由一个比较器和一个多路选择器构成。复杂度增长较快,但仍比门级设计好。
  3. 基于算术的设计:使用并行计数器计算输入中“1”的个数,然后与阈值比较。复杂度适中。
  4. 基于选择的设计:输出即为输入的中值。对于大规模输入,这通常是效率最高的方法。

对于多位字表决,需要特别注意。不能简单地对每个比特位独立进行多数表决,因为这样可能产生一个不属于任何原始输入字的无效结果。此时需要在字级别进行设计,确保输出是某个真实的输入值。

一种高效的递归设计阈值电路(如 n 中取 k 表决器)的方法如下:

function Threshold(x, n, L):
    if n == 0:
        return (L <= 0) ? 1 : 0  // 基础情况
    else:
        // 递归情况:考虑第一个输入 x[0]
        result_if_0 = Threshold(x[1:], n-1, L)    // x[0]=0时,仍需L个1
        result_if_1 = Threshold(x[1:], n-1, L-1)  // x[0]=1时,还需L-1个1
        return (x[0] == 0) ? result_if_0 : result_if_1

这种结构非常规整,适合VLSI实现,并且在面积和功耗上具有优势。

实际应用案例与总结 🚀

上一节我们探讨了表决器的设计细节,本节中我们来看两个著名的实际应用案例,并对本章内容进行总结。

NASA航天飞机(已于2012年退役)的机载计算机采用了五模冗余硬件。早期设计使用三个操作单元和两个备用(一温一冷)的混合冗余。后期则使用四个操作单元和一个备用的混合冗余,以提高安全性。此外,软件系统也采用了设计多样性,即由两个独立的团队开发不同版本的软件,以避免共模故障。

日本新干线子弹列车 采用了三重双工系统,即六模冗余。它包含三对双工模块,每对内部通过比较进行故障检测,然后对三对模块的输出进行表决。

空间与时间冗余的混合使用 可以优化性能。例如,在一个需要两次加法和一次乘法的计算中,通过合理的调度,时间冗余带来的时间开销可以小于简单重复计算两倍的时间。进一步地,如果将单个加法器拆分为两个更小的加法器分别用于时间冗余的不同阶段,可以构成空间与时间混合的冗余方案,提高资源利用率和故障检测效果。


本节课总结 🎯

在本节课中,我们一起学习了故障屏蔽的核心概念与技术。我们从故障屏蔽与故障避免的对称性入手,了解了交织冗余逻辑、摩尔-香农继电器电路等经典思想。重点掌握了三模冗余及其推广N模冗余的原理,并对比了动态、静态和混合冗余的优缺点。我们还探讨了时间冗余、操作数变换以及冗余系统测试性设计等实际问题。最后,深入分析了表决器这一关键部件的多种设计方法,并了解了故障屏蔽技术在航天、高铁等领域的实际应用。通过这些内容,我们建立了如何利用冗余技术来屏蔽故障、提升系统可靠性的完整知识框架。

009:第13-15章 错误检测与自检模块 🛡️

在本节课中,我们将要学习错误检测码的基本概念、分类、评估方法以及一个重要的应用——自检模块设计。课程内容涵盖教材的第13章(错误检测)和第15章(自检模块)。

概述

错误检测是容错计算的核心技术之一。通过为数据添加冗余信息(即编码),我们可以在不进行完全复制(100%冗余)的情况下,检测出数据处理或传输过程中发生的错误。本节课首先介绍错误检测码的基本原理,包括汉明距离、各类错误模型以及常见的检错码(如奇偶校验码、校验和码、恒定权重码、循环码和算术检错码)。随后,我们将探讨如何利用这些检错码来设计能够在运行时检测自身内部故障的电路模块,即自检模块。

错误检测基础

上一节概述了课程目标,本节中我们来看看错误检测的基本思想。最直观的错误检测方法是完全复制,即使用两个相同的电路计算函数 F(X),并比较它们的输出。如果输出不同,则表明存在错误。

公式:

输出比较 = 电路1输出 XOR 电路2输出

若结果为0,则无错误;若结果为1,则检测到错误。

然而,完全复制带来了100%的硬件冗余。我们的目标是使用远低于此的冗余度(例如10%-15%)来实现错误检测,这就需要借助错误检测码

双轨编码

双轨编码是复制法的一种变体,它使用 XX的补码 来表示数据。虽然冗余度仍是100%,但它能检测所有单向错误(即所有错误位变化方向相同,例如全由0变为1)。

编码: 数据 X 被编码为 (X, X的补码)
检错: 使用XNOR门比较两个电路的输出,正常工作时输出应互补。

汉明距离

汉明距离是衡量两个等长比特串差异程度的指标,定义为它们对应位不同的数量。

公式:

汉明距离(A, B) = 计数(A[i] ≠ B[i])

检错和纠错能力直接由编码中所有码字之间的最小汉明距离决定。

以下是不同最小汉明距离(d)对应的能力:

  • d = 2: 可检测单比特错误
  • d = 3: 可检测双比特错误,或纠正单比特错误
  • d = 4: 可纠正单比特错误并检测双比特错误(SECDED)。
  • d = 5: 可纠正双比特错误,或检测四比特错误,或纠正单比特错误并检测三比特错误。

通用关系为:若要纠正 c 个错误并检测 e 个错误,需满足 d ≥ c + e + 1e ≥ c

错误模型与分类

为了设计有效的检错码,我们需要对可能发生的错误进行建模和分类。

以下是主要的错误分类:

  • 按影响位数: 单比特错误、多比特错误。
  • 按错误类型
    • 翻转: 0变1或1变0。
    • 擦除: 位值丢失(无法判断是0还是1)。
  • 按相关性
    • 随机错误: 错误位之间独立发生。
    • 相关错误: 错误位由共同原因导致,如字节错误(影响一个字节的所有位)或突发错误(影响连续多个位)。
  • 按对称性
    • 对称错误: 0->1和1->0翻转概率相近。
    • 非对称/单向错误: 错误翻转主要集中于一个方向。
  • 按持久性: 在本课程术语中,错误本质上是永久性的(如寄存器存储了错误值),而瞬态故障可能导致临时性的信号扰动。

检错码的应用与评估

在计算机系统中,数据会经历存储、传输和处理阶段。传统上,编码主要用于保护存储和传输阶段的数据。在处理(如算术运算)阶段,数据需要先解码,此时会失去保护。

算术检错码(如AN码、剩余码)是一类特殊的编码,允许直接在编码数据上进行运算,从而在整个处理流程中保持数据的保护状态。

评估一个检错码时,需考虑以下几个关键特性:

  • 冗余度: 增加的校验位数量与原始数据位数量的比值 R/K。目标是在满足需求的前提下尽可能低。
  • 编/解码复杂度: 包括电路复杂度和时间延迟。简单的编解码有利于降低成本和延迟。
  • 检错能力: 码能检测的错误类型和数量,例如单错检测、突发错误检测、单向错误检测等。
  • 闭包特性: 编码数据是否能在不解码的情况下直接进行所需运算(如加法、乘法)。这是一个理想但并非普遍具备的特性。

常见检错码示例

上一节我们介绍了评估检错码的维度,本节中我们来看看几种具体的检错码。

1. 奇偶校验码

最简单的检错码。为数据添加一个校验位,使得整个码字中“1”的个数为偶数(偶校验)或奇数(奇校验)。

  • 冗余度: 极低(1个校验位)。
  • 能力: 仅能检测单比特错误,无法检测双比特错误。
  • 公式: 对于数据位 D0, D1, ..., Dk-1,偶校验位 P = D0 XOR D1 XOR ... XOR Dk-1

2. 校验和码(如UPC-A码)

通过加权求和并取模来生成校验位。例如,UPC-A条形码使用权重(奇数位权重3,偶数位权重1)和模10运算。

  • 能力: 可检测所有单数字错误和大多数(非全部)数字对换错误。
  • 过程
    1. 计算奇数位和 × 3 + 偶数位和。
    2. 找到下一个10的倍数。
    3. 校验位 = (下一个10的倍数) - 上述和值。

3. 恒定权重码(如Berger码)

码字中“1”的个数(权重)是恒定的。Berger码通过统计数据位中“0”的个数,并将其二进制表示作为校验位。

  • 能力: 可检测所有单向错误
  • 冗余度: 对于k位数据,需要 ⌈log2(k+1)⌉ 位校验位,效率较高。

4. 循环码

任何循环移位后仍是有效码字的线性码。常用多项式表示和运算。编码通过数据多项式乘以生成多项式实现。

  • 能力: 特别擅长检测突发错误。一个r阶生成多项式可以检测所有长度 ≤ r 的突发错误。
  • 特点: 具有简单的串行编码/解码电路(由生成多项式决定的移位寄存器结构)。

5. 算术检错码

专为算术运算设计,将错误建模为加减2的幂次。

  • AN码(乘积码): 将数据 N 编码为 A * N(A为奇数,如3、15)。可检测所有单算术错误(单个2的幂次错误)。
  • 剩余码: 将数据 N 编码为 (N, C),其中 C = N mod A。运算时,数据部分和校验部分分别处理并比较。冗余度低,且校验部分电路简单。

自检模块设计

本章我们将探讨错误检测码的一个重要应用:设计能够在线检测自身内部故障的电路模块,即自检模块

自检模块的核心思想是:让电路处理编码的输入,并产生编码的输出。电路被设计成:当内部发生特定类型故障(如单固定型故障)时,其输出会变为无效码字,从而被后级的码校验器检测到。

一个关键假设是:功能模块和校验器不同时故障。由于两者独立且故障率低,此假设合理。

自检模块有四种可能状态:

  1. 两者均正常:正常工作。
  2. 功能正常,校验器故障:可能误报错,但输出正确,属于安全失效
  3. 功能故障,校验器正常:错误被检测到。
  4. 两者均故障:不允许发生(概率极低)。

完全自检与自监控设计

  • 完全自检: 电路不仅是自检的,还是自测试的。即对于所考虑的每个故障,至少存在一个正常输入能激活该故障并导致无效输出。这样,在第二个故障发生前,第一个故障就能在日常操作中被发现。
  • 自监控设计: 针对一个较小的初始故障集(如单固定型故障)实现完全自检。假设更复杂的故障在发展为严重故障前,会先表现为初始故障集中的某个故障。这样可以在复杂故障造成危害前将其检测出来。

自检测试器设计

校验器本身也必须可靠。单线输出的校验器若输出端固定为“无错”状态,则会失效。因此,自检测试器通常采用双轨输出(如01或10表示正常,00或11表示错误),这样即使一条输出线固定,错误模式也能被识别。

例如,一个针对奇校验的自检测试器,当输入有奇数个1时,输出应为01或10;否则输出00或11。

总结

本节课中我们一起学习了错误检测与自检模块的核心知识。

我们首先从基本的复制法和双轨编码入手,引入了汉明距离这一关键概念,它定义了编码的检错和纠错能力。接着,我们系统地对错误模型进行了分类,这是选择或设计合适检错码的基础。

然后,我们探讨了多种常见的检错码,包括简单的奇偶校验码、用于商品标识的校验和码、能检测单向错误的Berger码、擅长处理突发错误的循环码,以及专门用于算术运算保护的算术检错码。每种码都有其特定的冗余度、检错能力和应用场景。

最后,我们将检错码应用于电路设计,学习了自检模块的概念。通过让电路处理编码数据,并精心设计使其内部故障导致无效输出,我们可以构建出能够在线检测自身故障的可靠模块。我们还了解了完全自检自监控设计等更高级的设计理念,以及设计自检测试器以确保整个检测链条可靠性的重要性。

掌握这些知识,是设计高可靠、高可用计算系统的重要基础。在下节课中,我们将继续学习纠错码及其在冗余磁盘阵列等领域的应用。

010:错误纠正与RAID技术 🛡️💾

在本节课中,我们将学习错误纠正码的核心概念及其在构建高可靠性磁盘阵列(RAID)中的重要应用。我们将从简单的纠错码入手,逐步探讨更高效的编码方案,并了解如何利用这些技术来保护大规模数据存储。


从三模冗余到高效纠错码

上一节我们介绍了错误检测的基本原理。本节中,我们来看看如何不仅检测,还能纠正错误。

三模冗余是我们已知的一种简单纠错方法。它将数据 x 编码为三个副本 (x, x, x),这带来了 200% 的冗余度。计算在三个通道上独立进行,最终通过多数表决器输出结果。只要三个通道中不超过一个出错,就能得到正确结果。

然而,三模冗余的冗余度过高,成本昂贵。我们的挑战是设计出纠错能力强,但冗余度低得多的编码方案,例如将冗余度从200%降低到20%-30%。

为了纠正一个 n 比特码字中的任意单比特错误,我们需要 r 个冗余校验位,且满足:
2^r > n
因此,对于 k 个数据比特,我们至少需要 log₂ k 个校验位。这是纠错码所需冗余度的理论下限。


纠错码的基本原理与评估

纠错码的工作原理可以形象地理解:有效的码字(绿色点)位于码空间内,无效的非码字(红色点)位于码空间外。当某个码字因错误变为一个非码字时,只要这种映射关系不是“多对一”(即多个不同码字不会因错误变成同一个非码字),我们就可以根据接收到的非码字唯一地确定原始的正确码字,从而纠正错误。

评估纠错码时,我们主要关注以下几个维度:

  • 冗余度:纠错能力越强,通常所需冗余度越高。目标是寻求高纠错能力与低冗余度之间的平衡。
  • 编/解码复杂度:包括电路复杂度和所需时间。
  • 纠错能力:能纠正的错误类型(如单比特、双比特、突发错误等)。
  • 纠检结合能力:某些码能在纠正一定数量错误的同时,检测更多数量的错误,使系统更安全。

要纠正 c 个错误并额外检测 d 个错误(d > c),要求码的最小汉明距离为:
c + d + 1
例如,汉明码的一种变体可以纠正单比特错误并检测双比特错误,其最小码距为 4。


二维奇偶校验码:一个直观的例子

让我们从一个概念简单、易于理解的纠错码开始:二维奇偶校验码。

假设我们有 9 个数据比特,将其排列成 3x3 的方阵(蓝色部分)。然后,我们为每一行和每一列计算一个偶校验位(绿色部分),并在右下角增加一个总校验位。

以下是编码过程:

  • 第一行 011 含有两个 1,因此其行校验位为 0(保持偶数个1)。
  • 第二行 001 含有一个 1,因此其行校验位为 1
  • 以此类推计算所有行、列校验位。
  • 右下角的总校验位,无论是作为最后一行的校验位还是最后一列的校验位,计算结果一致。

这种编码方式可以纠正任何单比特错误。当某个数据比特出错时,其对应的行校验和列校验都会失败,两者的交点即可精确定位错误位置并进行纠正。

它能检测所有双比特错误,但无法定位。某些特定的三比特错误模式可能被误判为单比特错误,从而导致错误“纠正”。因此,这是一个单纠错-双检错码。

其冗余度随数据规模增大而改善:对于 9 个数据比特,需要 7 个校验位(冗余度 ~78%);对于 100 个数据比特,需要 21 个校验位(冗余度 ~21%)。


汉明码:经典的高效单纠错码

汉明码是最著名的单比特纠错码之一,它接近理论下限,非常高效。

以最小的汉明码 (7,4) 码为例:它有 4 个数据比特 (d3, d2, d1, d0) 和 3 个校验比特 (p2, p1, p0)。校验位由数据位的特定子集异或产生:

  • p0 = d0 XOR d1 XOR d2
  • p1 = d0 XOR d1 XOR d3
  • p2 = d1 XOR d2 XOR d3

编码需要 3 个异或网络。解码时,我们计算伴随式:即重新计算校验位并与接收到的校验位比较,得到 3 比特的伴随式 (s2, s1, s0)

  • 如果伴随式为 000,则没有错误。
  • 如果伴随式非零,则其二进制值直接指向出错的比特位置(1 到 7),只需翻转该比特即可纠正错误。

冗余度方面:4 个数据位配 3 个校验位,冗余度为 75%。但随着数据位增加,冗余度急剧下降:26 个数据位需 5 个校验位(~19%),120 个数据位仅需 7 个校验位(~6%)。

汉明码的矩阵表示与电路实现

汉明码可以用矩阵简洁表示。校验矩阵 H 乘以接收到的码字向量,即可得到伴随式。在二进制运算中,矩阵乘法中的“乘加”被替换为“与-异或”操作。

通过重排校验矩阵的列,使其按二进制数 1 到 7 顺序排列,则伴随式的值直接对应出错比特的列号。这允许一个非常简单的纠错电路:一个 3-8 解码器对伴随式解码,其输出(除代表“无错”的 0 输出外)直接控制对应比特进行异或翻转。

任何汉明单纠错码都可以通过增加一个全校验位,升级为单纠错-双检错码。这个额外的校验位是所有数据位和原始校验位的异或和,它使得系统能区分单比特错误和双比特错误。


算术纠错码:保护数值运算

上一节我们讨论了算术错误检测码(如余数码)。本节我们看看如何扩展它们以纠正错误。

对于 n 位数据,单算术错误是指加上或减去一个 2^ii 从 0 到 n-1)。如果我们使用两个互质的模数进行余数校验,例如模 7 和模 15,则可以纠正单算术错误。

其原理是:每个特定的错误值(如 +2^3-2^5)会在两个余数校验中产生一个独特的错误模式(伴随式)。通过查表或计算,可以唯一确定错误的位置和类型,从而纠正。

对于模 (2^a - 1) 和模 (2^b - 1)双余数码,最多可以保护 a * b 个数据位。例如,a=3(模7),b=4(模15)可保护 12 位数据。冗余度相对较高(12 位数据需 7 位校验,约 58%),但其优势在于码对算术运算是封闭的,可以在不剥离校验位的情况下直接进行运算,为运算过程提供保护。


RAID技术:纠错码在磁盘阵列中的应用 🗂️

现在,我们将纠错码的知识应用于构建高可靠、大容量的存储系统——独立磁盘冗余阵列。

磁盘基础与性能瓶颈

现代磁盘(HDD)是机械装置,其访问时间由三部分组成:

  1. 寻道时间:磁头移动到目标磁道的时间,与移动距离有关,约数毫秒。
  2. 旋转延迟:磁盘旋转使目标扇区到达磁头下的平均时间,约为半圈所需时间,约数毫秒。
  3. 传输时间:实际读写数据的时间,通常远小于前两者。

早期试图用昂贵特制磁盘(如每磁道一头)来匹配CPU速度,但成本过高。RAID 的思路是:使用大量廉价、低可靠性的商用磁盘,通过冗余和组织方式来获得高容量、高性能和高可靠性

RAID 级别概述

以下是主要的 RAID 级别及其思想:

  • RAID 0(条带化):将数据分段分布到多个磁盘上。优点:大幅提升读写吞吐量。缺点:无冗余,任一磁盘失效将导致所有数据丢失。
  • RAID 1(镜像):所有数据在另一磁盘上保存完整副本。优点:可靠性极高(并行系统)。缺点:存储开销翻倍(100%冗余)。
  • RAID 3(带专用校验盘的条带化):数据条带化分布,并使用一个专用磁盘存储所有条带的奇偶校验信息(按字节/比特计算)。优点:冗余度低,读性能高。缺点:校验盘成为写操作的瓶颈;重建失效盘时,若第二块盘再失效,数据将丢失。
  • RAID 5(分布式校验):与 RAID 3 类似,但将校验信息均匀分布到所有磁盘上,消除了专用校验盘的瓶颈。这是目前最常用的方案之一。
  • RAID 6(双校验):类似 RAID 5,但使用两种独立的校验计算(如 P 和 Q),可以容忍任意两块磁盘同时失效。这显著降低了在重建漫长过程中发生第二块盘失效而导致数据丢失的风险。

校验组大小与性能权衡

在 RAID 5/6 中,校验组大小(参与同一个校验计算的数据盘数量)是一个关键设计参数。

  • 小组:重建时涉及的磁盘少,对系统其他部分性能影响小,但冗余开销相对较高。
  • 大组:冗余开销更低,但重建时涉及大量磁盘,耗时长,且在此期间系统更脆弱。

性能研究表明,校验组大小对不同访问模式(小读、大读、小写、大写)的影响不同,需要根据具体应用负载进行权衡。

RAID 的可靠性分析

RAID 系统的平均无故障时间远高于单盘。假设单盘 MTTF 为 M,平均修复/重建时间为 R,则:

  • RAID 1MTTF ≈ M² / (2 * R)
  • RAID 5MTTF ≈ M² / (G * R)G 为校验组大小)
  • RAID 6MTTF ≈ M³ / (G² * R²)

可见,通过引入冗余,尤其是像 RAID 6 这样能容忍多故障的配置,可以极大地提升存储系统的整体可靠性。


总结

本节课中,我们一起学习了错误纠正的核心技术。我们从三模冗余的高开销入手,探讨了如何利用奇偶校验、汉明码等编码技术,以更低的冗余度实现单比特乃至多比特错误的纠正。我们深入了解了汉明码高效的单纠错原理及其矩阵化实现。接着,我们将视野扩展到算术运算领域,看到了如何用余数码保护数值计算。最后,我们聚焦于这些技术的重大实际应用——RAID 磁盘阵列,分析了从 RAID 0 到 RAID 6 各级别的设计思想、优缺点及可靠性模型,理解了如何用廉价磁盘构建高可靠、高性能的大规模存储系统。

011:故障诊断与备用冗余

在本节课中,我们将要学习故障诊断的基本概念,包括系统级故障(即“功能失常”)的检测与诊断方法,以及如何利用备用冗余模块来维持系统运行。课程内容涵盖诊断模型、诊断算法以及备用模块的不同工作模式。

概述:系统级故障诊断

上一节我们讨论了逻辑层面的故障。本节中,我们来看看系统层面的故障,我们称之为“功能失常”。功能失常指的是处理器、内存、磁盘等较大功能单元出现的问题。为了与门级故障区分,有时也称之为系统级故障。

自诊断与互诊断

一种诊断功能失常的方法是通过自诊断。由于现代功能单元(如处理器、内存控制器)内置了智能,它们能够检测自身的内部问题。但一个自然的问题是:如何信任一个可能已经失常的单元对自身的诊断结果?

以下是实现可信自诊断的一种分层方法:

  1. 首先,测试系统的一个核心小部分(内核),使用大量测试确保其工作正常。
  2. 然后,利用这个可信的内核去诊断单元A。
  3. 接着,用已确认正常的单元A和内核去诊断单元B。
  4. 依此类推,逐步扩展系统的可信部分,直至覆盖整个系统。

在互诊断中,内核可以向待测单元发送一个种子。待测单元基于此种子运行自检程序,并生成一个结果返回给内核。内核预存了该种子对应的预期结果。通过比较实际结果与预期结果,内核可以判断该单元是否正常。如果结果匹配,则该单元可被信任。

PMC诊断模型

在由多个互连单元构成的系统中,我们可以定义一个测试图。图中的有向边表示一个单元测试另一个单元。测试结果记为 d_ij,其值为0或1:

  • d_ij = 0 表示测试单元i认为被测试单元j正常。
  • d_ij = 1 表示测试单元i认为被测试单元j失常。

所有测试结果构成一个稀疏的诊断矩阵D。这个模型被称为PMC模型。我们假设:一个正常的测试单元给出的诊断结果是可信的;而一个失常的测试单元给出的诊断结果是不可信的(可能为0或1,视为随机)。

一步可诊断性

如果一个系统运行一次诊断测试,就能根据结果(症候)唯一地识别出所有失常单元(假设失常单元数量不超过t个),则称该系统是一步t可诊断的

一步t可诊断的必要条件包括:

  1. 单元总数 n >= 2t + 1(即正常单元必须占多数)。
  2. 每个单元至少被其他t个单元测试。

一个四单元系统的测试图示例表明,它最多只能是一步1可诊断,而无法做到一步2可诊断。

诊断算法

给定测试结果(诊断矩阵),确定哪些单元失常是一个计算问题。

一种朴素算法的复杂度为 O(n^3)。它通过假设某些单元的标签(正常/失常),利用已知的可信诊断结果推断其他单元的标签,如果产生矛盾则回溯。

更高效的算法(如 O(n^2.5))可以通过构建L图来将问题转化为寻找L图的最小顶点覆盖问题。L图中的边 (i, j) 表示当单元j已知正常时,可以推断单元i失常。找到的顶点覆盖即对应可能的失常单元集合。

顺序可诊断性

有些系统无法做到一步识别所有失常单元,但可以做到顺序t可诊断。这意味着在存在不超过t个失常单元时,系统总能通过多次诊断步骤,至少明确识别出一个失常单元。识别后,可以更换该单元,然后在剩余单元中继续诊断。

对于一个有向环系统,顺序可诊断性有特定的条件。例如,一个五单元环虽然不是一步2可诊断的,但可以是顺序2可诊断的。在某些诊断症候下,虽然无法区分是单个单元失常还是两个单元同时失常,但两种情况下都指向同一个单元是失常的,因此可以安全地移除并更换它。

备用冗余

诊断出失常单元后,下一步是通过重配置将其移除或替换。备用冗余是实现这一目标的关键技术。

故障检测方法

在启用备用模块前,需要可靠地检测到功能失常。检测方法包括:

  • 周期性测试:按固定间隔运行诊断程序。
  • 自检设计:模块在运行中持续进行自我检查。
  • 故障停止/静默:模块失常时自动停止工作,避免传播错误,其失效可通过看门狗定时器检测。
  • 编码技术:对存储的数据或控制信号进行编码(如添加校验位),一旦编码被破坏即可立即检测。
  • 监控:基于应用或系统特性的特定监控机制(如监视总线活动、程序执行流程)。

备用模块类型

根据准备状态,备用模块可分为:

  • 热备用:与主模块同步运行,状态完全一致,切换延迟极短,但能耗和失效率较高。
  • 冷备用:处于断电状态,切换时需要上电、初始化,延迟较长,但更节能且失效率低。
  • 温备用:处于上电但空闲状态,是热备用和冷备用之间的折中方案。

冗余策略

  • 高冗余策略:为每个活跃模块配备专用备用模块,通过一个N选1开关切换。简单但冗余度高。
  • 低冗余策略:少量备用模块为多个活跃模块共享(如一个备用模块负责替换一个处理器阵列中的4个单元)。这降低了硬件开销,但要求备用模块具备更多的连接端口以接管不同位置单元的功能,设计更为复杂。

总结

本节课中我们一起学习了系统级故障(功能失常)的诊断与处理。我们介绍了PMC诊断模型,讨论了一步可诊断性与顺序可诊断性的概念及条件。随后,我们探讨了在诊断出故障后,如何利用不同类型的备用模块(热、温、冷)通过重配置来维持系统运行,并比较了高冗余与低冗余策略的优劣。下一讲,我们将继续学习本教材第五部分的剩余章节。

012:故障容忍与鲁棒并行处理

在本节课中,我们将学习系统级的故障容忍方法,特别是通过系统重构来应对模块故障。课程内容涵盖教材的第18章和第20章,我们将探讨重构的基本概念、具体方法以及鲁棒并行处理的设计思路。

系统级重构概述

上一节我们介绍了故障诊断,本节中我们来看看系统级的故障容忍,这主要通过系统级重构方法实现。与之前讨论的设备级重构不同,这里的重构单元在规模和能力上都更为复杂。

一个系统由模块化资源(如处理器、内存、磁盘、网络控制器)和互连机制组成。冗余资源可以减轻模块故障的影响,前提是系统具备绕过故障单元进行重构的能力,并且故障已被正确诊断。

为了实现故障容忍,一个基本要求是在任何源模块和目标模块之间存在多条路径。

互连网络与路径冗余

以下是实现路径冗余的关键概念:

  • 节点/边不相交路径:指除源节点和目标节点外,不共享任何节点或边的多条路径。如果存在 k 条这样的路径,则系统可以容忍最多 k-1 个链路或节点故障,因为每个故障最多只影响一条路径。
  • 性能影响:当最短路径因故障不可用时,通信可能需要更长的路径,导致性能下降。

公式:存在 k 条边不相交路径的两个节点,可以提供容忍 k-1 个链路故障的能力。

处理器阵列的重构方法

用于缺陷容忍或良率提升的重构方案,同样可以应用于处理器阵列。以下是几种常见的重构方法:

  • 行列旁路:通过多路复用器等开关,可以旁路整行或整列的处理器。这种方法简单,但可能浪费完好的模块。开关状态可由集中式控制单元设置,也可由相邻的健康模块进行本地控制。
  • 可编程连接:类似于FPGA中的方法,通过可编程开关盒连接模块端口与垂直/水平通道。灵活性越高(每个端口可连接的通道越多),成本和控制开销也越大。
  • 总线隔离:在总线架构中,必须隔离故障模块以防止其干扰总线通信。例如,可以使用“总线守护者”机制,要求一个模块必须获得其他两个模块的许可才能连接总线。另一种方法是使用触发器控制模块的读写使能,当触发器复位时,模块与总线的连接被禁用。

代码示例(总线隔离控制逻辑)

// 假设 q 是一个控制触发器
if (q == 1) {
    // 模块可以读写总线
    enable_read_write();
} else {
    // 模块与总线断开
    disable_read_write();
}

故障安全模块与日志恢复

当模块发生故障并被替换时,需要恢复其数据和状态信息,以便新模块能无缝接替工作。

  • 故障安全模块:一种高冗余设计,例如使用 K+1 个模块。只有当所有 K+1 个模块提交相同请求,且系统未处于停止状态时,才能对稳定存储进行更改。否则,系统将设置停止变量并进入静默的安全状态。
  • 日志恢复:这是最常见的恢复机制。日志在稳定存储中记录对数据库的所有更改及其时间戳。
    • 前写日志:要求在覆盖稳定存储中的对象之前,先写入一条撤销日志条目。这确保了即使更改后立即发生故障,也有日志条目可以用于回滚。
    • 作用:日志用于撤销未完成事务的影响,以及重做那些效果尚未写入稳定存储的事务。

鲁棒并行处理

鲁棒并行处理不严格区分“工作模块”和“备用模块”,所有资源都处于活动状态。当部分处理器故障时,系统利用剩余资源继续运行,可能以较低的性能水平完成任务。

以下是评估互连网络鲁棒性的一些关键属性:

  • 网络规模 P:处理器数量越多,可容忍的故障数量可能越多。
  • 节点度:节点的连接数。均匀或较高的节点度通常有利于鲁棒性。
  • 直径:网络中任意两节点间的最长最短路径长度,反映最坏情况通信延迟。
  • 对分宽度:将网络分成两半所需切割的最少链路数。较大的对分宽度有助于降低随机通信的延迟。
  • 连通性 κ:任意两节点间不相交路径的最小数量。连通性为 κ 的网络可容忍最多 κ-1 个故障而不断开。
  • 故障直径:移除最多 κ-1 个节点后,剩余网络直径的变化。
  • 宽直径:在所有节点对的不相交路径集合中,最长路径的长度。

自适应路由

当网络中存在故障时,需要自适应路由算法来动态选择可用路径。

  • 集中式路由:源节点基于全局故障信息计算路径。在大型系统中,维护和分发全局信息开销大。
  • 分布式路由:每个节点根据本地信息(如邻居健康状况)做出路由决策。需要避免死锁(消息相互等待)和活锁(消息永远无法到达目的地)。
  • 凸故障区域:如果故障节点集中在凸区域内,简单的绕行算法(如维序路由的变体)通常有效。对于非凸故障区域,路由算法会变得非常复杂。

鲁棒多级互连网络

多级互连网络(如蝶形网络)常用于连接处理器和存储器。其传统缺点是任意源-目标对之间通常只有唯一路径。

  • 额外级蝶形网络:通过增加一个开关级,可以为源-目标对提供两条独立路径,从而容忍单个开关故障。消息可以选择从原始第一级或新增的第二级开始路由,提供了冗余路径。

总结

本节课我们一起学习了系统级故障容忍的核心方法。我们探讨了通过提供节点/边不相交路径来实现冗余,并介绍了多种处理器阵列的重构技术,包括行列旁路、可编程连接和总线隔离。我们还了解了故障安全模块的设计理念和基于日志的恢复机制。最后,我们引入了鲁棒并行处理的概念,分析了互连网络的鲁棒性属性,并简要介绍了自适应路由算法以及如何通过增加冗余级来增强多级互连网络的容错能力。这些方法共同构成了构建可靠计算系统的基础。

013:退化允许与弹性算法 🛡️

在本节课中,我们将要学习容错计算中的两个核心概念:退化允许弹性算法。我们将探讨系统如何在发生故障时优雅地降低性能,以及如何通过软件和算法层面的设计来增强系统的容错能力。

概述 📋

本课程内容基于教材第六部分“适应与行为失误”的前两章。本章节将涵盖第21章“退化允许”和第23章“弹性算法”。我们将学习如何设计系统,使其在组件发生故障时能够继续运行,尽管性能可能下降,而不是完全崩溃。

第21章:退化允许 📉

上一节我们介绍了课程的整体框架,本节中我们来看看什么是“退化允许”。

优雅退化的定义

优雅退化指的是计算机系统的性能或其他属性在发生故障时能够逐渐地、可控地下降。这有时也被称为故障软化行为。一个能够优雅退化的系统等同于一个故障软化系统。

其对立面是系统在发生最轻微的故障时就彻底崩溃。优雅退化是可取的,因为它允许系统在部分功能丧失的情况下继续运行。因此,防止完全失败意味着我们允许系统优雅地退化。

实现优雅退化的要求

为了实现故障预防和优雅退化,系统需要满足以下要求:

  • 快速故障诊断:必须能立即发现系统某部分出现故障。
  • 有效隔离故障单元:能够隔离发生故障的元件。
  • 在线修复能力:无需关闭系统其他部分即可修复或更换故障部件,例如通过热插拔模块实现。
  • 避免灾难性故障:必须避免影响系统多个部分的故障,否则优雅退化将无法实现。

对于单一或有限的故障,系统必须能够快速诊断、隔离故障元件,并在系统其他部分继续运行时进行在线修复。

退化允许并非自动实现

即使一个系统拥有20个处理器,也并不意味着当其中一个处理器发生故障时,其他19个能自动继续正确运行。这个特性必须被设计到系统中。

退化管理

退化管理涉及在系统能力降低时采取的行动,这将在下一讲中详细讨论。主要包括:

  • 任务优先级排序:执行对系统运行更关键的任务。
  • 系统监控:跟踪系统在退化模式下的运行状态。
  • 逆转故障影响:使系统恢复到完整或较低退化状态。
  • 恢复正常运行:尽快使系统恢复正常。

故障软化系统的可执行性

故障软化系统的性能水平可以从顶部的完整功能到底部的崩溃(无功能)。在这之间存在不同级别的功能状态,接近完整的称为退化,功能大幅降低的称为部分失败

系统随时间运行,可能从完整状态因故障降至下一级。只要系统在这些退化状态之间波动,它就能继续运行。如果能够进行在线修复,系统可以恢复到较低退化状态甚至完整状态。

如果系统进入崩溃状态,则需要进行离线修复,这是不太理想的。在理想的故障软化系统中,我们应努力保持在退化状态,避免进入崩溃状态。

系统在各级性能状态下工作的时间所围成的面积,代表了系统完成的工作总量。我们希望最大化这个面积。

系统在发生完全故障前所完成计算的平均值,称为平均故障前计算量。这是一个评估此类系统的重要指标。对于一个永不进入完全故障状态的系统,这个值趋向于无穷大,这是最理想的状态。

从故障中恢复的步骤

当诊断出故障并移除故障单元后,系统需要执行一系列恢复步骤:

  1. 更新系统:更新操作系统资源表,使其能适应更有限的资源。
  2. 物理隔离故障单元:例如,通过总线守护机制防止故障单元干扰总线通信。
  3. 启动修复:进行物理修复或更换。在某些场景(如航天器)下,可能仅进行隔离。
  4. 创建新的工作配置
    • 排除故障的处理器、通道或控制器。
    • 避免使用损坏的磁盘扇区或文件。
    • 关闭噪声过大的通信信道。
    • 假设系统有足够的冗余,在移除部分资源后仍能执行主要任务。
    • 对于故障的内存部分,可通过虚拟地址映射将其重映射到其他正常区域;对于缓存,可以减少其大小继续运行。
  5. 恢复进程及相关数据:常用技术如检查点与回滚

稳定存储与日志

能够从故障中恢复的一个要求是拥有稳定存储,即不会丢失内容的存储(如闪存)。结合编码技术(如RAID)可以提供稳定性和可靠性。

日志对于恢复至关重要。当数据库或稳定存储发生更改时,我们将更改记录在日志中。如果发生故障导致更改丢失,我们可以利用之前保存的数据库状态和记录更改的日志来重建系统。

理想情况下,进程应在运行结束时才输出结果或更改数据库,这样如果进程因故障中止,不会对系统造成永久性损害。对于涉及执行器(如工业控制)的进程,其操作可能是不可逆的,设计时需要特别考虑。

检查点与回滚

这是一个非常重要的概念。对于运行时间可能超过系统平均故障间隔时间的计算任务,插入检查点是有效的解决方案。

检查点是系统在某个时间点状态的记录。如果故障发生在某个检查点之后,我们可以从该检查点重启计算,而无需从头开始,从而节省时间。然而,设置检查点本身也有开销。

检查点开销因回滚导致的计算重复开销之间存在权衡。检查点太少会导致大量计算重复;检查点太多则会导致设置开销过大。因此,存在一个最优的检查点间隔。

检查点示例分析

假设一个计算任务运行时间为 T,系统平均故障间隔时间为 MTTF(故障率 λ = 1/MTTF)。将任务分为 Q 个等长段,插入 Q-1 个检查点,每段运行时间为 T/Q,每个检查点开销为 T_cp

考虑一个简单的马尔可夫模型,系统从“任务未开始”状态,以概率 1 - λ(T/Q) 成功进入“完成一段”状态,或以概率 λ(T/Q) 因故障停留在原状态。最终目标是进入“任务完成”状态。

通过分析,包含检查点的总运行时间 T_total 可近似为:

T_total ≈ T / (1 - λT/Q) + (Q - 1) * T_cp

其中第一项是包含回滚重复的计算时间,第二项是检查点设置时间。

Q 求导并令导数为零,可求得最优分段数 Q_opt

Q_opt ≈ T * √(λ / T_cp)

这表明:

  • 任务时间 T 越长,最优检查点数量越多。
  • 故障率 λ 越高,最优检查点数量越多。
  • 检查点开销 T_cp 越大,最优检查点数量越少。

交互进程的检查点

当系统中有多个交互进程时,设置一致的检查点(称为恢复线)变得复杂。如果一个进程回滚,与之交互的其他进程可能也需要回滚以保持状态一致性,否则可能因丢失交互信息而导致错误。在最坏情况下,可能需要所有进程都回滚到起点。

事务处理中的最优检查点

在事务处理等场景中,回滚开销可能不是简单的重新计算,而是与故障发生点距离检查点的长度 x 成正比(例如 a + b*xa 为固定开销,b 为比例系数)。在这种情况下,最优检查点间隔 P_opt 的公式会有所不同:

P_opt ≈ √(2 * T_cp / (λ * b))

第23章:弹性算法 💡

上一节我们深入探讨了通过系统设计实现退化允许,本节中我们来看看如何通过算法和数据结构层面的设计来提升容错能力。

商用现货组件方法

从容错计算的历史来看,许多系统是从头开始设计的,这通常成本高昂。更实用的方法是使用商用现货组件来构建系统,然后在其之上通过软件或算法添加容错功能。

鲁棒数据结构

这是一种在现有非容错组件上实现容错的方法。目标是设计能够检测甚至纠正数据错误的数据结构。

列表保护

对于一个包含元素 X, Y, Z 的列表,其顺序也是信息的一部分。保护方法包括:

  • 加权校验和:计算 1*X + 2*Y + 3*Z。即使元素值不变但位置互换,校验和也会改变,从而检测错误。
  • 存储差值:额外存储相邻元素的差值(如 Y-X, Z-Y),作为一种重复形式,可增强错误检测能力。

链表保护

标准链表非常脆弱,一个损坏的指针就会导致部分数据丢失。保护方法包括:

  • 存储列表ID:每个节点存储所属列表的ID,如果指针错误指向其他列表的节点,可通过ID不匹配检测出来。
  • 使链表成环:可检测单个错误。
  • 使用双向链表:可检测并纠正单个指针错误。
  • 通用结论:一个链式数据结构的链接网络如果是双连通的(任意两节点间有两条独立路径),则它可以检测两个错误并纠正一个错误

二叉树保护

通过利用叶子节点的空指针,可以将其指向树中更高层的节点(例如根节点),从而将树转换为双连通网络,使其具备纠单错的能力。

数据多样性

同一信息用多种不同的数据形式表示。例如,一个矩形可以用长和宽 (x, y) 表示,也可以用对角线长度和夹角 (d, α) 表示,或用内切圆和外接圆半径 (r, R) 表示。

故障可能以相同方式影响相同数据的多个副本,但不太可能以相同方式影响多样化的数据表示,因此错误检测的可能性更高。

算法层面的容错:矩阵校验和

对于矩阵运算,可以通过添加校验行和校验列来构造一个完全校验和矩阵。对于矩阵乘法 Z = X * Y,有性质:Z 的完全校验和矩阵等于 X 的列校验和矩阵与 Y 的行校验和矩阵的乘积。

如果计算过程中发生错误,结果矩阵的校验和将不匹配,从而检测出错误。这种编码方案可以纠正单个错误,检测两个错误。但三个错误可能导致误纠。

总结 🎯

本节课中我们一起学习了容错计算中的两个重要方面。

首先,我们深入了解了退化允许的概念。系统不应在发生故障时立即崩溃,而应能够优雅地降低性能,在资源减少的情况下继续执行关键任务。我们探讨了实现这一目标的要求,并重点学习了检查点与回滚这一核心技术,分析了如何通过权衡开销来确定最优的检查点策略。

其次,我们探讨了弹性算法,即如何在软件和算法层面,而非仅仅硬件层面,提升容错性。我们介绍了鲁棒数据结构(如通过加权校验和保护列表、增强链表和二叉树)、数据多样性以及用于矩阵运算的校验和编码等方法。这些技术使得基于商用现货组件构建的系统也能具备较强的错误检测和恢复能力。

通过结合系统级的退化允许设计和算法级的弹性设计,我们可以构建出更健壮、更可靠的计算机系统。

014:退化管理与软件容错 🛡️

在本节课中,我们将要学习容错计算的第六部分,涵盖教材的第22章和第24章。我们将首先定义什么是退化管理,然后讨论可用于管理退化的各种方法。之前我们讨论了如何设计系统以允许退化发生,现在我们将探讨如何管理这些退化。

数据分布方法 📊

上一节我们介绍了退化管理的基本概念,本节中我们来看看管理退化的核心方法之一:数据分布方法。数据分布方法主要有两种类型:数据复制和数据分散。

  • 数据复制:这意味着我们拥有多个感兴趣数据项的副本。这样,如果包含一个数据副本的站点发生故障,导致该副本无法访问,我们仍然可以访问其他副本。数据复制在冗余量方面成本较高。
  • 数据分散:这种方法通过使用各种类型的编码方法来分散数据,从而避免高冗余。我们不完整地复制数据,而是将数据切割成片段,使得这些片段的子集足以恢复数据。这通常使用一种编码形式。

管理复制数据

以下是管理复制数据的一种对称方法示例。假设我们有九个数据副本,逻辑上排列成一个3x3的矩阵。

  • 写入法定数:定义为构成任意一行的三个副本。例如,顶行、中间行或底行都可以作为写入法定数。
  • 读取法定数:定义为构成任意一列的三个副本。

工作原理
当我们想要更新数据时,我们尝试更新所有九个副本。一旦我们收到来自构成一个逻辑行的三个副本的确认,我们就可以继续操作,无需等待其余副本更新。当我们想要读取数据时,只要我们能访问构成一列的三个副本就足够了。我们读取这三个副本,检查时间戳,识别具有最新时间戳的副本(即已更新的副本),然后使用该数据。这种方法使我们无需在每次更新数据时都等待所有九个副本更新,从而解决了因站点故障或响应缓慢而导致的长时间或无限期等待问题。

管理分散数据

类似的技术也可用于数据分散。以下是一个示例:我们有一个数据文件,将其编码并切割成六个片段,使用冗余编码,使得任意两个片段足以重建数据。

  • 写入法定数:定义为四个片段。
  • 读取法定数:也定义为四个片段。

工作原理
当我们想要更新数据时,我们尝试更新所有六个片段。一旦我们收到四个片段已更新的确认,就无需等待另外两个。当我们读取数据时,读取任意四个片段。因为写入集合(四个片段)和读取集合(四个片段)在总共六个片段中,这两个集合保证至少有两个公共片段。这两个公共片段包含了最新的数据,足以重建数据。这同样提供了灵活性,我们无需等待所有六个片段都正确更新才能继续。

分布式系统中的协调与协议 🤝

上一节我们讨论了数据管理,本节中我们来看看分布式系统中另一个关键问题:多个协作站点之间达成一致。这个问题最好通过一个难题来引入,即“两将军问题”。

两将军问题

想象两位将军G1和G2的部队驻扎在敌方城市外,他们需要协调行动同时进攻。他们唯一的通信方式是派遣信使穿过敌方领土。信使可能被俘、死亡或延迟。

  1. G1决定明天中午进攻,并派遣信使通知G2。
  2. G1不确定G2是否收到消息,因此不敢进攻,除非确信G2也知情。
  3. G2收到消息后,可以发送确认信使告知G1他已收到。
  4. 但G2无法知道G1是否收到了确认。如果G1没收到确认,他就不会进攻。
  5. 这个问题可以无限循环下去:G1发送对确认的确认,G2发送对确认的确认的确认……无论进行多少轮确认,都无法获得完全的确定性。

实际意义:这个问题类似于分布式事务,例如ATM取款。我们需要确保“ATM发放现金”和“银行计算机扣减余额”这两个操作要么都发生,要么都不发生,以保持系统一致性。

原子操作与提交协议

为了保持系统一致性,我们使用原子操作。实现原子操作的一种常见方法是两阶段提交协议

两阶段提交协议流程

  1. 一个站点被指定为协调者,其他站点为参与者。初始时,所有站点对于该事务都处于“安静”状态。
  2. 协调者决定开始执行事务,向所有参与者发送“开始”消息,然后进入“等待”状态。
  3. 参与者收到“开始”消息后,可以回复“是”(进入“等待”状态)或“否”(进入“中止”状态)。
  4. 如果任何参与者回复“否”,协调者收到后也进入“中止”状态,并通知所有参与者中止。
  5. 如果所有参与者都回复“是”,协调者则向所有参与者发送“提交”命令,并进入“提交”状态。
  6. 等待中的参与者收到“提交”命令后,也进入“提交”状态,并最终执行其部分事务。

问题:如果参与者在“等待”状态时,协调者发生故障,参与者可能会永久挂起。为了解决这个问题,引入了三阶段提交协议,它在“等待”和“提交”之间增加了一个“准备”状态,降低了因协调者故障而导致挂起的风险。

可靠的通信与故障分类 📡

我们讨论了通过复制或分散确保数据完整性,以及使用提交协议确保站点间协调。我们还需要站点之间各种形式的可靠通信。

点对点与广播通信

  • 点对点消息:使用编码(检错或纠错码)、确认超时机制。如果发送消息后未在特定时间内收到确认,则假定消息丢失并重发。这需要处理重复消息的机制。
  • 可靠广播:确保消息最终被所有节点接收。更高级的“原子广播”还保证所有节点以相同顺序接收消息。

故障严重性分类

根据严重程度,故障可分为以下几类:

  • 崩溃故障:站点完全停止工作,不进行任何通信。这是最良性的一类,因为它不会误导其他站点。
  • 遗漏故障:节点对某些输入不响应,表现为功能不完整。
  • 定时故障:节点响应过早或过晚(通常是过晚),响应时间不可靠。
  • 拜占庭故障:节点行为完全不可预测,可能不响应、错误响应或延迟响应。这是最严重的一类,通常由敌对接管导致,旨在以最有害的方式误导系统。

其他分布式系统服务 🔄

在分布式系统中,我们还需要其他服务,例如组群成员服务和负载平衡。

  • 组群成员服务:站点经常组成群组以协作执行特定事务。群组成员可能会变化。组群成员协议确保,尽管存在站点故障和通信错误,成员仍能可靠地了解群组的当前组成。
  • 重新映射与负载平衡:当站点发生故障时,我们可能需要重新映射计算以避免使用故障站点。同时,故障站点的负载会分布到其他站点,可能导致负载不平衡。负载平衡能够检测这种状况,并通过在站点间移动任务来重新平衡负载。

计算重新映射示例

假设一个计算有五个部分,在五个处理器上执行,并有一个备用处理器。

  • 为了验证计算正确性,可以进行时间冗余:存储第一次计算的结果,然后重复计算并比较。
  • 如果某个处理器存在永久性故障,重复计算可能会遇到相同错误。此时,可以重新映射计算:忽略故障处理器,让后续处理器接管其工作,使第二次计算使用不同的硬件资源,从而更有可能检测到问题。

可退化系统建模 📉

可退化系统可以处于完整功能状态,也可以处于若干退化状态(功能减少),以及我们希望永远不要进入的故障状态。

状态空间模型

  • 系统在状态间转移(例如,处理器故障导致从完整状态转移到退化状态)。
  • 修复操作可以将系统从退化状态移回更高级状态。
  • 这些退化状态充当缓冲区,防止系统直接进入故障状态。
  • 然而,存在因覆盖不完善而直接进入故障状态的可能性(即未检测到故障或系统无法重新配置以容忍该故障)。
  • 系统故障有两种机制:1) 因覆盖不完善导致的灾难性故障;2) 资源耗尽(例如,过多处理器故障)。

重要启示:添加更多备用资源(如冗余)有时可能无益,因为重新配置机制变得更复杂,从而增加了发生灾难性直接故障路径的概率。

软件容错 💻

现在,让我们转向第24章,探讨软件容错的一些关键概念。软件可靠性与硬件有本质不同。

软件可靠性与缺陷建模

  • 软件缺陷:主要是设计疏漏,而非运行偏差。软件通常每千行代码包含一个或多个缺陷。即使经过测试,一些细微的“残留缺陷”可能仍然存在。
  • 可靠性模型:软件可靠性也可以使用指数模型来近似:R(t) = e^{-K * F * t},其中 F 是软件中残留缺陷数量的估计值,K 是一个比例常数。
  • 缺陷消除模型:在测试初期,缺陷消除速率很高,但随着时间推移,速率会下降。一个简化的模型假设消除速率线性下降。通过测试,我们可以估计残留缺陷数量,从而评估软件可靠性。

软件容错技术

与硬件容错类似,软件也可以采用容错技术。

  1. N版本编程(静态冗余)
    • 类似于硬件中的三重模块冗余与表决。
    • 关键区别在于:软件副本必须是多样化的版本,由不同的团队、使用不同的算法、编程语言等独立开发,以避免共同的设计缺陷。
    • 一个裁决器(而非简单的表决器)比较各版本的输出,考虑到浮点误差和不同的执行时间,判断是否达成有效一致。
    • 挑战包括:开发成本高、多样性不一定保证缺陷独立、以及规范本身可能有误。

  1. 恢复块方法(动态冗余)
    • 类似于硬件中的动态冗余。
    • 首先运行一个主模块,并将其输出提交给一个接受测试
    • 如果通过测试,则输出被接受。
    • 如果未通过,则依次运行一个或多个备用模块,直到某个模块的输出通过接受测试。
    • 优点:备用模块通常更简单、开发成本更低,且只在需要时运行。
    • 挑战:设计一个有效且复杂度低于主计算的接受测试可能很困难。

  1. 混合方法
    • 结合N版本编程和接受测试的优点。
    • 例如,先运行少数几个(如三个)多样化版本并进行表决。如果达成一致,则输出结果。
    • 如果只有两个版本一致,则对一致的结果进行接受测试以增强信心。
    • 如果上述都失败,则运行额外的备用版本作为最终裁决。

总结 📚

本节课中我们一起学习了容错计算中关于退化管理与软件容错的核心内容。

  • 我们首先探讨了退化管理,重点介绍了通过数据复制数据分散,并结合读写法定数机制,来管理分布式系统中的数据可用性和一致性。
  • 接着,我们深入研究了分布式系统中的协调问题,通过“两将军问题”引出了达成一致的挑战,并介绍了两阶段提交三阶段提交协议来确保事务的原子性。
  • 我们还了解了可靠的通信机制、不同严重程度的故障分类,以及组群成员服务重新映射负载平衡等分布式系统服务。
  • 最后,我们转向软件容错,讨论了软件可靠性的特点、缺陷建模,并重点介绍了N版本编程恢复块方法这两种主要的软件容错技术,以及它们各自的优缺点和混合应用的可能性。

这些概念和方法对于设计和构建能够在组件故障时继续可靠运行的计算系统至关重要。

015:故障隔离与共识协议

在本节课中,我们将学习故障隔离与共识协议。我们将探讨如何通过收集故障数据、进行风险评估以及设计有效的故障检测与隔离机制来构建可靠的系统。课程内容涵盖故障意识、风险分析、故障避免策略、伦理考量,以及通过投票和共识协议(如拜占庭容错)来实现系统在部分组件故障时仍能达成一致决策。


故障意识与数据收集

上一节我们介绍了容错计算的基本模型。本节中,我们来看看如何通过收集和分析故障数据来建立对系统潜在风险的认知。

可靠系统设计的第一步是了解故障可能发生的方式和频率。如果不知道某种故障可能发生,就无法为其做好准备。因此,收集实验性故障数据至关重要。

以下是历史上一些系统故障原因的统计数据示例:

  • 贝尔通信研究、天腾电脑等系统:故障原因大致可分为硬件、软件、操作和环境。粗略平均来看,这三类原因导致的故障比例大致相当。
  • 天腾电脑非计划停机:超过一半的非计划停机由电源问题引起。这表明在设计可靠系统时,应特别关注电源供应和备份。
  • 硬件故障细分:在硬件故障中,约一半由磁盘存储问题导致。这强调了使用RAID等可靠存储方案的重要性。

这些数据虽然有些陈旧,但仍能提供有价值的见解。不幸的是,近年来,由于行业竞争加剧,制造商越来越不愿意公开分享详细的故障数据。


风险评估与心理因素

在了解了故障的可能性之后,我们需要评估其风险。风险通常定义为事件发生频率与其后果严重性的乘积。

然而,人类在评估和理解极小的概率方面存在困难。例如,死于流感的概率远高于死于核电站事故的概率,但后者往往更令人恐惧。这种心理偏差会影响我们对风险的判断和应对措施的优先级。

以下是一些影响风险感知的因素:

  • 导致风险低估的因素:对风险的熟悉度(如日常驾驶)、风险是工作的一部分、风险在时间或空间上遥远。
  • 导致风险高估的因素:事件的规模(如造成大规模伤亡)、事件的邻近性(发生在附近社区)。


故障检测与避免策略

为了限制故障造成的损害,及时的故障检测是最重要的前提。检测延迟越短,故障造成重大问题的可能性就越低。例如,在磁盘存储系统中,快速检测到问题可以显著降低数据丢失的概率。

除了检测,另一个关键策略是尽可能避免故障的发生。以下是一些设计高可靠系统的建议:

  • 限制新颖性:使用经过验证的方法和技术。
  • 进行彻底简化:减少系统中的组件数量,因为更少的组件意味着更低的故障概率。
  • 避免不必要的功能:每个额外功能都可能引入新的故障点。
  • 尽早实现简化版本:先让一个简单的原型工作,然后逐步迭代添加功能。
  • 建立错误报告激励机制:鼓励团队快速、彻底地报告错误。
  • 早期缩减目标与规范:避免项目过于雄心勃勃而导致后期无法完成。
  • 保持小型设计团队:小型团队通常沟通更高效。


伦理考量

作为计算领域的专业人士,我们有责任确保所设计系统的安全与福祉。主要的专业学会,如电气电子工程师学会(IEEE)和计算机协会(ACM),都制定了行为准则。

以下是IEEE伦理准则中的几个关键点:

  • 在决策时承担起保障公众安全、健康和福利的责任。
  • 及时披露可能危及公众或环境的因素。
  • 仅在接受过培训或有经验的技术任务中承担工作。
  • 寻求、接受并提供对技术工作的诚实批评,承认并纠正错误,并适当肯定他人的贡献。

遵守这些伦理原则是专业责任的一部分,有时可能需要付出代价,但这对保障公共利益至关重要。


共识与裁决:投票与数据融合

现在,我们转向如何在存在故障或分歧时达成共识。这通常通过“投票”或更广义的“数据融合”来实现。我们引入一套统一的术语:参与者提供意见(可能带有权重),融合器根据这些意见和权重生成结果

投票方案有多种类型:

  • 一致性投票:要求所有参与者意见一致。
  • 多数投票:要求结果权重超过总权重的一半。
  • 绝对多数投票:要求结果权重达到或超过总权重的三分之二。
  • 拜占庭投票:要求结果权重超过总权重的三分之二(严格大于)。
  • 相对多数投票:选择获得最高权重(不一定过半数)的意见。
  • 阈值投票:要求结果权重超过某个预设阈值。

中值投票是处理近似数值的一种有效方法。当存在明确多数时,中值就是多数值;当没有明确多数时,中值也能给出一个合理的折中结果。

对于加权投票,可以通过排序网络、权重合并网络和最大值选择器来设计融合电路。


拜占庭容错与分布式共识

在分布式系统中,节点可能发生“拜占庭”故障,即节点可能以任意方式(包括恶意地)运行,向不同节点发送不一致的信息。经典的“拜占庭将军问题”阐述了在此类故障下达成共识的挑战。

研究表明,要容忍 f 个拜占庭故障节点,系统需要至少 3f + 1 个节点。此外,故障隔离区域(节点)之间必须通过至少 2f + 1 条独立路径互联,并且信息交换至少需要 f + 1 轮。

例如,要容忍1个拜占庭故障,至少需要4个节点。这比简单的“多数原则”(需要 2f + 1 = 3 个节点)要求更高,因为拜占庭故障节点会故意扰乱信息。


总结

本节课中,我们一起学习了故障隔离与共识协议的核心内容。我们首先探讨了通过收集故障数据建立故障意识的重要性,以及如何进行风险评估。接着,我们讨论了及时故障检测和通过设计简化来避免故障的策略,并强调了专业伦理的责任。最后,我们深入研究了各种投票与数据融合方案,以及在分布式系统中应对拜占庭故障、达成可靠共识所面临的挑战和解决方案(如需要至少 3f + 1 个节点)。这些知识是构建能够在部分组件失效时仍能正确运行的高可靠系统的基石。

016:故障恢复与故障安全系统设计 🛡️

在本节课中,我们将学习课程的最后一部分内容,涵盖教材的第26章和第28章,以及附录中关于可靠计算历史和未来挑战的部分。我们将重点探讨故障恢复的策略以及如何设计故障安全系统。

故障恢复概述

尽管采取了各种预防措施,故障仍可能发生。故障恢复意味着处理这些故障的后果,并尝试通过各种手段使系统恢复正常运行。处理故障和恢复的关键在于拥有文档化的计划经过培训的人员。不能将处理故障的任务留给偶然性或人员的即兴发挥,必须对他们进行明确的培训。

上一节我们介绍了故障恢复的基本概念,本节中我们来看看一些与故障和恢复相关的术语。

故障相关术语

以下是描述故障和恢复时常用的一些术语及其定义:

  • 故障缓慢:系统性能逐渐下降,故障迹象不明显。
  • 故障软化:系统发生故障,但影响较轻微,可能不易立即察觉。
  • 故障安全:系统在发生故障时,会进入一个预定的安全状态。
  • 故障快速:从出现问题到系统明显失效的时间非常短。
  • 故障硬化:系统设计得使其故障难以被忽视(与故障软化相对)。
  • 故障停止:系统在检测到内部故障时停止响应或执行任何操作,是故障安全系统的一个子类。
  • 故障转移:当某个服务器或硬件资源发生故障时,将其功能和任务转移到另一个资源上,以继续服务。
  • 故障恢复:在故障转移后,当原故障资源修复后,将任务转移回原资源的过程。

复杂的系统往往存在难以检测的隐性故障,这比明显的显性故障更危险。因此,设计系统时应追求故障硬化故障快速,避免不必要的系统复杂性,并优先采用并发故障检测而非周期性测试。

人为因素与警告系统

处理故障和恢复的一个重要方面是人机交互。任何警告系统,无论是针对计算机故障还是自然灾害,都必须使其信息可信。如果警告信息被忽略、不被相信或导致不适当的行动,系统将无法有效运作。

以下是设计有效警告系统的关键点:

  • 可信性:警告必须可信。例如,频繁误报的火警会导致人们忽视真正的警报。
  • 信息充分性:警告应提供足够有用的信息。例如,汽车仪表盘上简单的“检查引擎”灯不如指明具体问题和严重程度的警告有效。
  • 操作员参与:在高度自动化的系统中(如自动驾驶汽车),如果系统非常成功,操作员可能会放松警惕。必须设计机制确保操作员在需要时能够保持专注并接管控制。

数据备份与计算机取证

数据备份是从故障中恢复的关键环节。个人和企业都需要定期备份重要数据。除了使用外部存储设备或云备份服务,一些实用技巧包括:通过电子邮件将文件副本发送给自己作为简易备份,以及避免直接覆盖文件,而是创建新版本的文件以保留修改历史。

计算机取证是一个快速发展的领域,涉及在计算机发生故障或安全事件后进行分析。计算机取证专家的工作包括:

  • 分析被告计算机以获取法律证据。
  • 恢复被删除的数据。
  • 对系统进行逆向工程或优化。
  • 分析被入侵的系统以确定入侵方法和攻击者。
  • 分析故障系统以确定故障原因。
  • 在计算机故障后恢复数据。

系统故障案例与教训

历史上许多复杂的系统项目因过于雄心勃勃而失败。这些失败案例提醒我们,在安全关键或大型系统中,应进行渐进式改进,而非试图一次性引入过多新技术和新方法。

失败是学习过程的一部分。正如亨利·彼得罗斯基所言:“复杂系统的成功掩盖了其接近失败的事实。” 从失败中吸取的教训往往比从成功中更多。

上一节我们回顾了故障恢复的各个方面,本节中我们将深入探讨如何设计故障安全系统

故障安全系统设计 🚦

在安全关键系统中,避免故障是最佳选择,次优选择是确保系统故障时是安全的。故障安全系统在发生无法容忍的不良事件时,会产生一组预定安全输出中的一个。

一个经典例子是交通信号灯。如果十字路口两边的信号灯同时显示红灯(所有交通停止),这是一个安全故障。如果同时显示绿灯,则是一个不安全故障,可能导致碰撞。因此,故障安全交通灯应设计为在故障时卡在红灯状态。

另一个例子是家用燃气灶的常明火。如果常明火意外熄灭,感温元件冷却会导致燃气阀门关闭,防止燃气泄漏,这是一个故障安全设计。

故障安全设计原则

安全工程领域提出了七条设计安全系统的原则:

  1. 使用屏障和互锁:限制对关键系统资源或状态的访问。
  2. 逐步执行关键操作:以增量方式而非单一步骤执行关键操作。
  3. 动态修改系统目标:以避免或减轻损害。
  4. 管理安全危机资源:确保在紧急情况下有足够的资源可用。
  5. 定期演练关键功能和安全特性:以评估和保持其可用性。
  6. 设计操作员界面:提供处理异常所需的信息和权限。
  7. 防御恶意攻击:保护系统免受恶意攻击。

故障安全规范与逻辑设计

故障安全规范必须完整,需要考虑即使在正常操作中不会出现、但因故障可能发生的状况。例如,一个轨道小火车在起点和终点有传感器。规范必须定义当两个传感器同时被触发(可能因传感器故障)时,控制系统应如何反应。

对于数字系统,可以设计故障安全组合逻辑。例如,一个采用双轨编码(用01代表0,10代表1)的电路,如果两条输出线都卡在1而产生不安全的“11”输出,可以通过一个安全触发器将输出强制设置为安全的“00”。

同样,可以设计故障安全状态机。通过使用伯格码等编码方式,并按照特定方式实现次态逻辑,可以确保在发生单向错误时,系统永远不会进入错误的有效状态,而只会进入可检测的无效状态并保持在那里。

可靠计算的历史与未来挑战

可靠计算的历史可以追溯到早期计算机,如捷克科学家安东宁·斯沃博达建造的采用三模冗余的SAPO计算机,以及美国喷气推进实验室为长期太空任务设计的自测试修复STAR计算机原型。

展望未来,我们面临诸多挑战:

  1. 器件缩小的诅咒:纳米技术使器件更小,但可靠性降低,需要新的冗余和测试方法。
  2. 云计算的安全与可靠性:将数据和计算置于云端带来了安全和控制权方面的挑战。
  3. 小型化与低功耗设计:模仿人脑的高能效处理方式是重要方向。
  4. 确保数据长期保存:需要解决存储介质寿命和读取技术过时的问题。
  5. 故障与入侵的交互:必须确保系统在发生故障时仍能保持安全。
  6. 可靠性墙:系统组件增多会降低整体可靠性,这成为提升性能的制约因素。

总结

在本节课中,我们一起学习了故障恢复的策略和故障安全系统的设计。我们了解了从制定计划、培训人员,到处理人为因素和进行数据备份的完整恢复流程。重点掌握了故障安全设计的核心思想,即系统在发生不可容忍的故障时,必须进入预定的安全状态,并通过具体例子(如交通灯、燃气灶、数字电路)理解了其实现方法。最后,我们回顾了可靠计算领域的历史,并展望了未来面临的主要挑战。本课程建立了一个关于容错与可靠计算的框架,希望大家能在此基础上,根据未来工作和学习的需要,深入探索相关的技术细节。

posted @ 2026-03-29 09:31  布客飞龙II  阅读(24)  评论(0)    收藏  举报