软件可靠性与系统容错
Software Reliability & System Fault Tolerance — 第 9 章核心知识体系
01基本概念
在规定的条件下,在规定的时间内,软件不引起系统失效的概率。该概率是系统输入和系统使用的函数,也是软件中存在的缺陷函数;系统输入将确定是否会遇到已存在的缺陷(如果缺陷存在的话)。
定义的四要素
① 规定的时间
软件可靠性只体现在运行阶段,以"运行时间"作为度量(包括运行后工作与挂起的累计时间)。由于程序路径选取的随机性,运行时间属于随机变量。
② 规定的条件
主要指软件的运行环境,涉及支持硬件平台、操作系统、数据库、中间件、其他支持软件、输入数据格式和范围及操作规程等。不同环境下软件可靠性不同。
③ 所要求的功能
软件可靠性还与规定的任务和功能有关。要完成的任务不同,软件的运行情况会有所区别,则调用的子模块就不同(包括程序选择路径不同),其可靠性也就可能不同。
④ 不引起失效的概率
用"内在缺陷"和"外在失效"的关系来描述,使可靠性可量化评估。用概率描述纯随机事件,合理可行。
软件可靠性与硬件可靠性的四个区别
- 复杂性: 软件比硬件复杂得多,导致软件可靠性比硬件可靠性问题严重。
- 物理退化: 硬件可靠性问题主要由于物理退化所致;软件不存在物理退化,一个正确的软件任何时刻均可靠;然而,一个正确的硬件元器件或系统,则可能在某个时刻失效。
- 唯一性: 软件是唯一的,软件复制不改变软件本身;而任何两个硬件不可能绝对相同。(这是为什么概率方法在硬件可靠性领域取得巨大成功,而在软件可靠性领域不令人满意的原因)
- 版本更新较快: 硬件更新周期通常较慢,定型一般就不会更改;软件产品通常受需求变更、缺陷修复的需要,造成版本更新较快,给可靠性评估带来较大难度。
02定量描述与指标
规定时间的三种概念
- 自然时间(日历时间): 人们日常计时用的年、月、周、日等自然流逝的时间段。
- 运行时间: 软件从启动开始,到运行的累计时间。
- 执行时间(CPU 时间): 软件实际占用 CPU 执行的时间。
常用可靠性指标
| 指标 | 含义 |
|---|---|
| 失效概率 | 软件在规定时间内不能完成规定功能的概率,记为 F(t) |
| 可靠度 R(t) | 在规定的条件、规定的时间内,软件不引起系统失效的概率,R(t) = 1 - F(t) |
| 失效强度 | 单位时间内软件系统失效的概率,即 f(t) = dF(t)/dt |
| 失效率(风险函数) | 在 t 时刻软件还没有失效的条件下,单位时间内软件失效的概率,Z(t) = f(t) / R(t) |
| MTTF | Mean Time To Failure,平均失效前时间(平均无故障时间) |
| MTBF | Mean Time Between Failure,平均失效间隔时间 |
| MTTR | Mean Time To Repair,平均修复时间 |
03影响可靠性的五大因素
构建可靠性模型前,需要分析影响因素。首先考虑主要因素:缺陷的引入、发现和清除。
- 缺陷的引入取决于软件产品的特性和软件的开发过程特性。
- 缺陷的发现依靠用户对软件的操作方式、运行环境等(即运行剖面)。
- 缺陷的清除依赖于失效的发现和修复活动及可靠性方面的投入。
从技术角度看的五大影响因素
① 运行剖面(环境)
软件可靠性的定义是相对运行环境而言的,一样的软件在不同运行剖面下,可靠性表现不一样。
② 软件规模
软件大小,一个只有数十行代码的软件和几千、几万行代码的软件不能相提并论。
③ 软件内部结构
主要取决于软件结构的复杂程度,一般来说,内部结构越复杂的软件,所包含的软件缺陷数就可能越多。
④ 软件的开发方法和开发环境
例如,与非结构方法相比,结构化方法可以明显减少软件的缺陷数。
⑤ 软件的可靠性投入
在软件生命周期中对可靠性活动的投入。
04广义 vs 狭义可靠性测试
软件可靠性问题已被越来越多的软件工程专家所重视。可靠性问题的重要性体现在五个方面:
- 软件失效可能造成灾难性的后果(如 Fortran 程序少逗号致美宇宙飞行失败)。
- 软件的失效在整个计算机系统失效中的比例较高(某机构统计 80% 与软件有关)。
- 相比硬件可靠性技术,软件可靠性技术很不成熟。FTA、FMEA 等在硬件领域比较成熟,但在软件领域尚未定型。
- 与硬件元器件成本急剧下降形成鲜明对比的是,软件费用呈有增无减的势头。
- 计算机技术日益广泛应用,系统对软件的依赖性越来越强。
广义与狭义的区别
为了最终评价软件系统的可靠性而运用建模、统计、试验、分析和评价等一系列手段对软件系统实施的一种测试。
过程包括:确定可靠性目标 → 定义运行剖面 → 设计测试案例 → 实施测试 → 测试问题集 → 排错 → 分析影响可靠性的因素 → 建模 → 分析数据 → 可靠性评价。
为了获取可靠性数据,按预先确定的测试用例,在软件的预期使用环境中,对软件实施的一种测试。也叫"软件可靠性试验"(Software Reliability Test)。
它是面向缺陷的测试,以用户将要使用的方式来测试软件,每一次测试代表用户将要完成的一组操作,使测试成为最终产品使用的预演。
可靠性测试目的(三方面)
- 发现软件系统在需求、设计、编码、测试和实施等方面的各种缺陷。
- 为软件的使用和维护提供可靠性数据。
- 确认软件是否达到可靠性的定量要求。
05软件可靠性建模(10 大类模型)
| 模型类别 | 代表模型 |
|---|---|
| ① 种子法模型 | 利用捕获/再捕获抽样技术估计程序中错误数 |
| ② 失效率类模型 | JM 模型、Schick-Wolverton 模型、改进的 Schick-Wolverton 模型、Moranda 的几何泊松模型、Goal Okumoto 不完全排错模型 |
| ③ 曲线拟合类模型 | 用回归分析方法研究软件复杂性、缺陷数、失效率、失效间隔时间(含参数与非参数方法) |
| ④ 可靠性增长模型 | Duane 模型、Weibull 模型、Wagoner Weibull 改进模型、Yamada Osaki 的逻辑增长曲线、Gompertz 的增长曲线 |
| ⑤ 程序结构分析模型 | Littewood 马尔可夫结构模型、Cheung 的面向用户的马尔可夫模型 |
| ⑥ 输入域分类模型 | Nelson 模型、Bastani 的基于输入域的随机过程模型 |
| ⑦ 执行路径分析方法模型 | Shooman 分解模型 |
| ⑧ 非齐次泊松过程模型(NHPP) | Musa 的指数模型、Goel Okumoto NHPP 模型、S 型可靠性增长模型、超指数增长模型、Pham 改进的 NHPP 模型 |
| ⑨ 马尔可夫过程模型 | 完全改错的线性死亡模型、不完全改错的线性死亡模型、完全改错的非静态线性死亡模型 |
| ⑩ 贝叶斯模型 | 利用失效率的试验前分布和当前的测试失效信息,评估软件可靠性。如连续时间的离散型马尔可夫链、Shock 模型 |
Musa Okumoto 的模型属性分类
- 时间域: 自然/日历时间 vs 执行(CPU)时间
- 失效数类: 无限时间内发生的失效数是有限的还是无限的
- 失效数分布: 泊松分布型 vs 二项分布型
- 有限类: 用时间表示的失效强度的函数形式
- 无限类: 用经验期望失效数表示的失效强度的函数形式
06软件可靠性管理(六阶段)
软件工程各个阶段可能进行的主要软件可靠性活动:
-
1. 需求分析阶段
确定可靠性目标 → 分析可能影响可靠性的因素 → 确定可靠性的验收标准 → 制定可靠性管理框架 → 制定可靠性文档编写规范 → 制订可靠性活动初步计划 → 确定可靠性数据收集规范 -
2. 概要设计阶段
确定可靠性度量 → 制定详细的可靠性验收方案 → 可靠性设计 → 收集可靠性数据 → 调整可靠性活动计划 → 明确后续阶段的可靠性活动的详细计划 → 编制可靠性文档 -
3. 详细设计阶段
可靠性设计 → 可靠性预测(确定可靠性度量估计值)→ 调整可靠性活动计划 → 收集可靠性数据 → 明确后续阶段计划 → 编制可靠性文档 -
4. 编码阶段
可靠性测试(含于单元测试)→ 排错 → 调整可靠性活动计划 → 收集可靠性数据 → 明确后续阶段计划 → 编制可靠性文档 -
5. 测试阶段
可靠性测试(含于集成测试、系统测试)→ 排错 → 可靠性建模 → 可靠性评价 → 调整可靠性活动计划 → 收集可靠性数据 → 明确后续计划 → 编制可靠性文档 -
6. 实施阶段
可靠性测试(含于验收测试)→ 排错 → 收集可靠性数据 → 调整可靠性模型 → 可靠性评价 → 编制可靠性文档
07★ 可靠性设计技术(核心重点)
实践证明,保障软件可靠性最有效、最经济、最重要的手段是在软件设计阶段采取措施进行可靠性控制。这是论文题的关键论点!
软件可靠性设计的定义
三大设计原则
- 软件可靠性设计是软件设计的一部分,必须在软件的总体设计框架中使用,并且不能与其他设计原则相冲突。
- 软件可靠性设计在满足提高软件质量要求的前提下,以提高和保障软件可靠性为最终目标。
- 软件可靠性设计应确定软件的可靠性目标,不能无限扩大化,并且排在功能度、用户需求和开发费用之后考虑。
三大设计技术总览
① 容错设计
对于软件失效后果特别严重的场合,如飞机飞行控制系统、空中交通管制系统及核反应堆安全控制系统等
② 检错设计
对无须在线容错的地方或不能采用冗余设计技术的部分,但对可靠性要求较高的场合
③ 降低复杂度设计
简化软件结构,缩短代码长度,优化数据流向,处于合理阈值之内
08★ 容错设计三大技术(核心重点)
① 恢复块设计(Recovery Block)
程序的执行过程可以看成是由一系列操作构成的。恢复块设计就是选择一组操作作为容错设计单元,从而把普通的程序块变成恢复块。被选择用来构造恢复块的程序块可以是模块、过程、子程序和程序段等。
一个恢复块包含有若干个功能相同、设计差异的程序块文本:
- 每一时刻有一个文本处于运行状态;
- 一旦该文本出现故障,则用备份文本加以替换,从而构成"动态冗余"。
② N 版本程序设计
核心是通过设计出多个模块或不同版本,对于相同初始条件和相同输入的操作结果,实行多数表决,防止其中某一软件模块/版本的故障提供错误的服务,以实现软件容错。
(1) 使软件的需求说明具有完全性和精确性。这是保证软件设计错误不相关的前提,因为软件的需求说明是不同设计组织和人员的唯一共同出发点。
(2) 设计全过程的不相关性。它要求各个不同的软件设计人员彼此不交流,程序设计使用:
- 不同的算法
- 不同的编程语言
- 不同的编译程序
- 不同的设计工具
- 不同的实现方法
- 不同的测试方法
为了彻底保证软件设计的不相关性,甚至提出设计人员应具有不同的受教育背景,来自不同的地域、不同的国家。
③ 冗余设计
改善软件可靠性的一个重要技术。软件冗余与硬件冗余的关键区别:
在软件系统中,如果采用相同两套软件系统互为备份,其意义不大!因为在相同的运行环境中,一套软件出故障的地方,另外一套也一定会出现故障。
软件冗余设计技术实现的原理是:在一套完整的软件系统之外,设计一种不同路径、不同算法或不同实现方法的模块或系统作为备份,在出现故障时可以使用冗余的部分进行替换。
冗余设计的成本分析:
- 设计开发完成同样功能但实现方法完全不同的两套软件系统,需要的费用可能接近于单个版本软件开发费用的两倍。
- 但采用冗余技术设计软件所增加的额外费用肯定远低于重新设计一个版本软件的费用(因为大多数设计花费如文档、测试以及人力都是有可能复用的)。
- 冗余设计还可能导致软件运行时存储空间、内存消耗以及运行时间有所增加,需要在可靠性要求和额外付出代价之间做出折中。
检错技术(对比容错)
检错技术实现的代价一般低于容错技术和冗余技术,但它有一个明显的缺点:不能自动解决故障,出现故障后如果不进行人工干预,将最终导致软件系统不能正常运行。
采用检错设计技术要着重考虑四个要素:
| 要素 | 说明 |
|---|---|
| ① 检测对象 | 包含两个层次:检测点和检测内容。检测点放在容易出错的地方和出错对软件系统影响较大的地方;检测内容选取有代表性的、易于判断的指标。 |
| ② 检测延时 | 从软件发生故障到被自检出来是有一定延时的。如果延时长到影响故障的及时报警,则需要更换检测对象或检测方式。 |
| ③ 实现方式 | 最直接的实现方式是判断返回结果,如果返回结果超出正常范围则进行异常处理。计算运行时间也是常用技术,如果某个模块或函数运行超过预期时间,可判断出现故障。此外还有置状态标志位等多种方法。 |
| ④ 处理方式 | 大多数检错采用"查出故障 → 停止软件系统运行 → 报警"的处理方式。也有采用不停止或部分停止软件系统运行的情况,由故障是否需要实时处理来决定。 |
降低复杂度设计
软件和硬件最大的区别之一就是软件的内部结构比硬件复杂得多。软件复杂度用于定量描述软件的复杂程度,常分为:
- 模块复杂性: 主要包含模块内部数据流向和程序长度两个方面。
- 结构复杂性: 用不同模块之间的关联程度来表示。
在设计时考虑降低软件的复杂性,使之处于一个合理的阈值之内,这是提高软件可靠性的有效方法。
其他技术的应用尝试
人们尝试着把硬件可靠性设计中比较成熟的技术,如故障树分析(FTA)、失效模式与效应分析(FMEA)等运用到软件可靠性设计领域。但由于软件与硬件内部性质的巨大差异,这些技术在软件可靠性设计领域的应用效果和范围极其有限。
09★ 系统配置技术(必考重点)
通常在系统配置中可以采用相应的容错技术,通过系统的整体来提供相应的可靠性,主要有双机热备技术和服务器集群技术。
双机热备技术
"心跳"机制
双机热备系统采用"心跳"方法保证主系统与备用系统的联系。所谓"心跳",指的是主从系统之间相互按照一定的时间间隔发送通信信号,表明各自系统当前的运行状态。
一旦"心跳"信号表明主机系统发生故障,或者备用系统无法收到主机系统的"心跳"信号,则系统的高可用性管理软件认为主机系统发生故障,立即将系统资源转移到备用系统上,备用系统替代主机工作,以保证系统正常运行和网络服务不间断。
双机热备的三种工作模式(必考)
| 模式 | 英文名 | 说明 |
|---|---|---|
| ① 双机热备模式 | Active / Standby | Active 服务器处于工作状态;Standby 服务器处于监控准备状态。服务器数据(包括数据库)同时往两台服务器写入(通常各服务器采用 RAID 磁盘阵列卡),保证数据即时同步。当 Active 故障时,通过软件诊测或手工方式将 Standby 激活。目前采用较多的一种模式,但存在一定计算资源浪费。 |
| ② 双机互备模式 | Active / Active(互为备机) | 两个相对独立的应用在两台机器同时运行,但彼此均设为备机。当某台服务器故障时,另一台可在短时间内将故障服务器的应用接管。但对服务器的性能要求比较高。 |
| ③ 双机双工模式 | 集群的一种形式 | 两台服务器均处于活动状态,同时运行相同的应用,保证整体系统的性能,实现负载均衡和互为备份。通常使用磁盘柜存储技术。Web 服务器或 FTP 服务器等用此种方式比较多。 |
• 双机热备:一主一备,备机不工作(资源浪费)
• 双机互备:两台都工作但跑不同应用,互为备机(性能要求高)
• 双机双工:两台都工作且跑相同应用,负载均衡(需磁盘柜)
服务器集群技术
大多数情况下,集群中所有的计算机拥有一个共同的名称,集群内任一系统上运行的服务可被所有的网络客户使用。
集群的核心特性
- 必须可以协调管理各分离的构件出现的错误和故障,并可透明地向集群中加入构件。
- 一个集群包含多台(至少二台)共享数据存储空间的服务器。其中任何一台服务器运行应用时,应用数据被存储在共享的数据空间内。
- 每台服务器的操作系统和应用程序文件存储在其各自的本地储存空间上。
集群内通信机制
集群内各节点服务器通过一个内部局域网相互通信。
- 当一台节点服务器发生故障时,这台服务器上所运行的应用程序将在另一节点服务器上被自动接管。
- 当一个应用服务发生故障时,应用服务将被重新启动或被另一台服务器接管。
- 当以上的任一故障发生时,客户都将能很快连接到其他应用服务器上。
10软件可靠性测试流程
软件可靠性测试由以下主要活动组成:
- 可靠性目标的确定
- 运行剖面的开发
- 测试用例的设计
- 测试实施
- 测试结果的分析
定义软件运行剖面
定义运行剖面首先需要为软件的使用行为建模,建模可以采用马尔可夫链来完成。用马尔可夫链将输入域编码为一个代表用户观点的软件使用的状态集。
开发使用模型的两种分层
- 用户级分层: 依赖于谁或什么能激励系统;考虑各种类型的用户以及他们如何使用系统。
- 用法级分层: 依赖于在测试状态下系统能做什么;要求考虑系统能够提供的所有功能。
定义使用概率的最佳方法
- 从现有系统收集到的数据(最优,如系统原型、前一版本)
- 与用户的交谈或对用户进行观察获得的信息
- 原型使用与测试分析的结果
- 相关领域专家的意见
在没有任何数据可用的情况下,只能将每个状态现有的弧分配相同的概率,这是最差的一种方法。
对于边界、跃迁情况和关键功能不应该用简单的运行剖面来对待,应该构造专门的运行剖面,补充统计模型之外的测试用例。
典型例子:飞机的飞行控制软件,在正常飞行、起飞、降落、地面运动和地面等待这 5 个状态中,尽管起飞和降落在运行剖面上只占很小百分比,但它们却占有很大的故障比例。
可靠性测试用例的组成部分
- 测试用例标识
- 被测对象
- 测试环境及条件
- 测试输入
- 操作步骤
- 预期输出
- 判断输出结果是否符合标准
- 测试对象的特殊需求
可靠性测试的特殊用例(重点考虑)
| 序号 | 测试目的 | 描述 |
|---|---|---|
| 1 | 屏蔽用户操作错误 | 考虑对用户常见的误操作的提示和屏蔽情况 |
| 2 | 错误提示的准确性 | 对用户的错误提示准确描述 |
| 3 | 错误是否导致系统异常退出 | 有无操作错误引起系统异常退出的情况 |
| 4 | 数据可靠性 | 系统应对输入的数据进行有效性检查,对冗余的数据进行过滤、校验和清洗 |
| 5 | 异常情况的影响 | 考察数据和系统的受影响程度,异常情况包括:硬件故障、网络故障、部分软件模块失效 |
四类可靠性数据
用时间定义的软件可靠性数据可以分为 4 类,这 4 类数据可以互相转化:
- 失效时间数据: 记录发生一次失效所累积经历的时间。
- 失效间隔时间数据: 记录本次失效与上一次失效间的间隔时间。
- 分组时间内的失效数: 记录某个时间区内发生了多少次失效。
- 分组时间的累积失效数: 记录到某个区间的累积失效数。
11软件可靠性评价
三个核心步骤
- 选择可靠性模型
- 收集可靠性数据
- 可靠性评估和预测
选择可靠性模型的判断维度
没有适用于所有软件系统的"最好"模型。可以从以下几个方面进行比较和选择:
模型假设是可靠性模型的基础,模型假设要符合软件系统的现有状况,或与假设冲突的因素在软件系统中应该是可忽略的。例如有的模型假定检测或发现的软件缺陷是立即排除掉的,而且排除时间忽略不计;如果现有系统对严重程度较低的软件缺陷不立即排错,这个模型显然不适用。
指模型根据现在和历史的可靠性数据,预测将来的可靠性和失效概率的能力,以及预测结果的准确程度。比较难于评价,任何模型只有在实践中加以实验和不断改善才能得到验证。
常用的数据分析图形
- 累积失效个数图形
- 单位时间段内的失效数的图形
- 失效间隔时间图形
试探性数据分析技术(EDA)
对失效数据图形进行一定的数字化分析,能发现和揭示出数据中的异常。对可靠性分析有用的信息包括:
- 循环相关
- 短期内失效数的急剧上升
- 失效数集中的时间段
这种分析方法常可以发现因排错引入新的缺陷、数据收集的质量问题及时间域的错误定义等问题。
12系统可靠性模型(划重点教材)
与系统故障模型对应的就是系统的可靠性模型。下面介绍几种常用的模型:
① 时间模型 — Shooman 可靠性增长模型
最著名的时间模型是由 Shooman 提出的可靠性增长模型,基于这样一个假设:
其中:
- τ 为调试时间
- Er(τ) 为在时刻 τ 软件中剩余的故障数
- E0 为 τ = 0 时软件中的故障数
- I 为软件中的指令数
- C 是比例常数
② 故障植入模型(Mills 模型,1972)
故障植入模型是一个面向错误数的数学模型,其目的是以程序的错误数作为衡量可靠性的标准。Mills 1972 年提出的基本假设:
- 程序中的固有错误数是一个未知的常数。
- 程序中的人为错误数按均匀分布随机植入。
- 程序中的固有错误数和人为错误被检测到的概率相同。
- 检测到的错误立即改正。
Basin 1974 年的两步查错法
考虑到实施植入错误时遇到的困难,Basin 提出了两步查错法:由两个错误检测人员独立对程序进行测试,检测到的错误立即改正。
③ 数据模型(Nelson 模型, 1973)
对于一个预先确定的输入环境,软件的可靠度定义为在 n 次连续运行中软件完成指定任务的概率。
基本方法:
R1 = 1 - P1
R(n) = R1n = (1 - P1)n
其中 E 为输入集,Ee 为导致软件差错的所有输入的集合。
组合模型(容错系统可靠性最常用方法)
组合模型是计算机容错系统可靠性最常用的方法。一个系统只要满足以下条件,就可以用组合模型来计算其可靠性:
- 系统只有两种状态:运行状态和失效状态。
- 系统可以划分成若干个不重叠的部件,每个部件也只有两种状态。
- 部件的失效是独立的。
- 系统失效当且仅当系统中的剩余资源不满足系统运行的最低资源要求(系统的状态只依赖于部件的状态)时。
- 已知每个部件的可靠性(可靠性指可用度或可靠度等概率参数)。
组合模型的基本思想
- 枚举所有系统状态: 假设系统被划分为 n 个部件,则系统状态是一个 n 维向量,一个具有 n 个部件的系统共有 2n 个状态。
- 计算每个系统状态的概率
- 可靠性计算
13考点速记卡
容错:故障发生时自动处理(高代价,极重要场合)
检错:发现故障并报警,需人工干预(低代价,但不能自动恢复)
降复杂度:从源头预防,简化结构
恢复块:同一时刻只有一个文本运行 → 故障切到备份(动态冗余)
N 版本:多版本同时运行 → 多数表决
冗余:不同路径/算法的备份(切忌完全相同的两套软件!)
不同算法、不同语言、不同编译程序、不同设计工具、不同实现方法、不同测试方法
甚至:不同教育背景、不同地域、不同国家
热备 = 一主一备,备机闲着(浪费)
互备 = 各跑自己的,互相做对方备机(性能要求高)
双工 = 一起跑同一个,负载均衡(用磁盘柜)
Shooman 时间模型(1972 年前后)→ 基于故障数的增长
Mills 故障植入模型(1972)→ 植入人为错误,统计估计
Nelson 数据模型(1973)→ 输入域概率分析
"可靠性设计技术 + 系统配置技术"是软考论文题的常见组合。建议背诵:
- 三大可靠性设计原则(部分、前提、目标顺序)
- 容错三技术(恢复块、N 版本、冗余)的差异与适用场合
- 双机三模式(热备、互备、双工)的区别与典型应用
- "心跳"机制原理
- FTA、FMEA 等硬件技术在软件领域应用极其有限(易考反向选项)
• 软件冗余 ≠ 简单的两套相同软件备份(关键词:不同路径/算法/实现)
• 检错技术无法自动恢复(需人工干预)
• 软件不存在"物理退化",但版本更新快
• Shooman 模型最大难点:确定调试前故障数
• N 版本的核心是"多数表决",而非"多份运行"