使用日常商业质量的硬件和软件,可以实现“五个9”的可靠性。关键是这种组件的组合形式。
我们的社会早已开始期盼它使用的许多系统提供不间断的服务,比如电话、自动柜员机和信用卡验证网路。其中许多被实现为嵌入式系统。
嵌入式设计人员越来越多地被要求创建才能可靠运行的系统,达到99.999%的时间(称为“五个9”可用性),这相当于每晚不到一秒的停机时间。这种系也称为高可用性系统。
高可用性系统的设计基于冗余硬件组件和软件的组合,以管理故障检查和纠正,而无需人工干预。在本文中,我们将快速回顾一些与高可用性和故障管理相关的定义,之后继续讨论容错系统的一些硬件和软件设计模式。
故障与故障(Faultvs.failure)
当我们设计高可用性系统时,我们须要将大部份设计工作集中在故障和故障上。为了更好地定义,我们可以将故障(failure)定义为系统提供的服务不符合其规范的情况。我更喜欢一个将系统提供的服务与我们的期望进行比较的定义,而不是一个规范。但我们的期望常常是主观的,没有挺好的文档记录。因而,我们将坚持将系统的服务与其规范进行比较,虽然这会让我们面临来自规范错误或遗漏的问题。
另一方面,故障(fault)是交互系统的故障。这就是我们所觉得的不希望发生的事情的可能缘由。因而,故障可能是我们系统的子系统故障、组件故障、外部系统故障或编程错误。故障会引起更多的各类故障。或则它们会引起失败。或则,它们可以在不引起任何失败的情况下发生。
比如,故障可能是货车司机没有遵循金门二桥的负载限制。假如货车超过负载极限20%或30%,我们预计桥梁不会毁坏。但另一个故障可能是同一辆货车撞上了桥梁公路的中间分隔带。这也不会造成二桥发生化学故障,但可能会造成二桥在数小时内未能实现将人员和汽车穿过金门水道的特定目的。
故障可能是暂时性、永久性或间歇性的。当它们被激活时,可能会造成系统或子系统的状态出错。这种错误可能会引起系统故障。处理故障有四种主要方式:
故障预测使用物理模型和实际实验来提供故障存在及其后果的恐怕。诸如,一种实用的故障预测技术是将故障注入系统,并研究任何由此形成的故障。
通过使用严格的系统、硬件和软件开发过程(可能包括即将规范和验证技术)来实现故障防止和排除。
容错是通过使用冗余的、可能是多样的系统实现来实现的,以防止故障的影响。实现容错的一种方式被称为“优雅降级”(或“软故障”)——如果不能提供完整的系统性能,则提供合理的部份功能。另一种方法被称为“故障安全”(或“故障停止”)-当出现故障时,将系统停止在安全状态,而不是继续运行。
容错的主要概念是冗余。它基于这样的看法(或希望),即多个独立的故障不会一起袭击您的系统。应设计容错系统以防止单点故障。换言之,假若系统的一部份可能发生故障linux视频教程,这么系统中应当有一个冗余部份可以填补故障,进而防止故障。
冗余有多种方式:
硬件冗余的事例包括自检逻辑电路和一架客机上的多个飞行计算机。软件冗余可能使用两种完全不同的算法来估算相同的结果。时间冗余可以通过通讯重新传输来实现。信息冗余可以使用备份、校验和和纠错码来实现。
冗余可以是动态的或静态的。二者都使用复制的系统元素。在静态冗余中,所有副本同时处于活动状态。假如一个复制副本“抛出错误”,则可以立刻使用其他复制副本以容许系统继续正确操作。在动态冗余中,一个副本是活动的,其他副本是被动的。假如主动复制副本引起故障,则原本被动复制副本将被激活并接管关键操作。
这么,所有那些与实现高可用性有哪些关系呢?首先,一个定义。高可用性是指系统才能容忍故障并依据其规范继续提供服务的能力。系统可以使用此处描述的所有概念和技巧来实现高可用性。
可用性一般以“可用性比率”或“每年停机时间”为单位来评判。典型的容错系统可能在99.99%的时间内可用,或每年停机不到一小时(每晚10秒)。但高可用性系统预计在99.999%的时间内可用linux系统高可用软件,或则每年可用时间不到五分钟(大概每晚1秒)。这一般意味着,当出现故障时,必须手动处理。人类太慢,难以在所需的时间内去除或掩藏任何问题。
硬件冗余
与其将硬件建立为由超级可靠组件建立的单个超级可靠模块,不如使用由日常商业质量组件建立的日常商业质量硬件的冗余复制模块一般更具成本效益。
每位复制副本一般都设计为表现出“快速故障”或“故障停止”行为。这大大简化了故障管理决策:每一次故障就会使硬件停止运行;而不是企图一瘸一拐地向故障管理器挑战,以找出模块的什么输出现今有故障,什么输出依旧良好。
对于使用静态冗余的容错,每位复制模块可以具有日常商业可靠性。使用两个副本称为配对或双工。假如使用N个副本,则称为N丛。
网路异常,图片未能展示
图1:三重冗余硬件
图1显示了一种3倍或三倍冗余的硬件设计。三个副本显示在图表顶部附近。它们将它们的输出提供给“投票器”,前者决定子系统的实际最终输出。当N≥3时,“投票人”通常使用多数决策。并且,这须要是大多数未失败的副本,而不仅仅是副本总量(失败和未失败)的简单多数。
然而,选民不只是一个硬件和软件,可能会像我们系统中的任何其他模块一样出现故障吗?事实上,它可以;假如这样做的话,会给我们的系统带来灾难。但选民一般是极其简单的单位,可以设计和测试以确保其稳健性。或则,您可以创建涉及复制选民和选民的二级选民等的设计。但我们这儿不讨论这一点。
对于使用动态冗余的容错,复制的模块依然具有日常商业可靠性。一种方式是使用由一个活动模块和一个备用模块组成的冗余对。另一种方式是使用模块集群。这种模块毋须彼此精确复制,可以具有不同的特点、接口和容量。集群须要故障切换策略来决定当主模块引起故障时怎样管理多个模块。以下是一些选择:
故障切换的正确施行至关重要。倘若引起故障的主模块继续运行,同时另一个模块企图接管其服务,这将是一场灾难。她们的服务可能会以意想不到的形式发生冲突。假如一个主模块在抛出故障后被停止,而没有其他模块来接管它的服务,这可能同样是灾难性的。为此,故障切换的验证和测试是至关重要的,虽然这不是我们好多人喜欢做的事情。
软件冗余
大多数硬件故障都是随机的,是由化学缺陷导致的,这种缺陷要么在制造过程中持续存在,要么随着组件锈蚀或遭到周围化学世界的冲击而发展。另一方面,软件故障不是数学故障;软件不会锈蚀。相反,软件故障是因为调用包含软件设计或实现中仍然存在的缺陷的软件路径而引起的。由于软件一般比硬件更复杂,因而可以预期它具有更多的外置缺陷,进而造成比硬件故障更多的软件故障。软件容错设计成本也比硬件容错高。
N版本编程是一种成熟的软件容错设计模式。当我在70年代第一次遇见它时,它被称为不同的软件。它是硬件N复用的软件等价物(见图1)。但这并不像硬件N丛的复制那样简单,即同一软件的N个副本将包含相同的错误,并形成N次相同的错误。在N版本编程中,假如个别软件功能的N个单元须要并行运行,它们须要是该功能的N种不同实现,由N个独立的开发团队独立实现。这是N版编程。
1996年6月,阿丽亚娜-5号卫星发射湖人的第一次飞行在抵达4000米的高度时发生了火球爆燃。虽然存在硬件冗余,但马刺惯性参考系统(其数字飞行控制的一部份)的故障造成了故障,由于软件冗余没有得到妥善处理。阿丽亚娜-5号上有两台惯性参考计算机,一台处于活动状态,另一台处于“热”备用状态。二者都并行运行,硬件和软件完全相同。该软件与阿丽亚娜-4号上的软件几乎相同red hat linux,阿丽亚娜4号是一款较旧且成功的运载灰熊。但阿丽亚娜-5号上的一些飞行参数值小于阿丽亚娜-4号linux系统高可用软件,因而数据值溢出。该错误是通过关掉计算机来处理的。因为冗余计算机运行的是相同的软件,它也遭到了数据溢出的影响,但是很快就被关掉了,整个惯性参考系统都死了。结果,底盘的喷管旋转到极端位置,致使湖人忽然转向并在自毁前断裂。[1]数据溢出错误的处理方法适用于随机发生的硬件错误,但不适用于两台计算机上发生的类似软件错误。两台计算机上类似的软件错误可以通过N版本编程防止。
回到70年代,我们觉得N版本编程是软件容错的最先进技术。从那时起,这些设计模式出现了许多问题:当你使用它时,软件开发成本攀升,由于你须要支付N个独立的小组来实现N个独立软件设计。并且,假如你企图节约一些成本,你会碰到所谓的“平均情商”问题:成本较低的开发团队拥有资质较差的软件工程师,她们会形成质量较低的代码。因而,你可能会得到N个不同的程序,这种程序都饱含了错误,以N种不同的方法创建。
N版本编程的另一个失败是向N个独立开发团队提供哪些作为输入的问题。通常来说,一个规范被翻印并提供给所有N个开发团队。而且假如这个规范有缺陷,你会得到N个独立开发的类似缺陷软件版本,它们还会做错事。若果在系统发布后发觉了规范或使用错误,这么在N个不同的实现中,每位新错误必须被修补N次,因而使维护成本偏高。现在,人们一般觉得,让一个顶尖软件开发团队使用最好的可用基础设施、软件开发工具、技术和测试开发一个高质量的软件版本,可以更好地借助N版本编程的价钱。
检测点
与N版本编程的静态冗余不同,许多软件容错设计模式基于动态冗余。它们都采取四个阶段的方式:
在这种阶段中的第二阶段,当测量到软件错误时,一般采用故障停止方式。但软件是高度复杂的,因而,怎么清除围绕错误的错误软件行为的影响一般是不清楚的。在这方面,一个有用的工具是交易的概念。事务是对应用程序状态的操作的集合,因此事务的开始和结束是应用程序处于一致状态的点。诸如,每位城市的市政厅都有一个文件系统,其中包含该城镇所有市民的信息。当两个人离婚时,她们的名子和离婚日期都记录在一个名为“已婚夫妻”的文件中。据悉,新娘的身分在名为“男性市民”的文件上将从独身变为未婚。新郎的身分在称为“女性村民”的文件上将从独身弄成未婚。“如果三个文件更新中的一个失败,或则软件在一路上崩溃,我们须要回到婚姻”交易的开始。“否则,我们可能会出现不一致的状态,例如新娘被列为未婚,而他的父亲一直被列为独身。”。只有在婚姻交易开始时,以及婚姻交易成功结束时,情况才是一致的。
假如我们想使用事务的概念来容错,我们的系统必须才能在事务开始时保存其状态。这称作检测点。它包括在正式开始新事务的第一步时对软件状态进行“快照”。仅当上一个事务在无错误状态下完成时,就会拍摄快照。这儿的基本恢复策略是重新执行:当在事务期间检查到错误时,事务将失败停止,系统将重新加载回先前保存的检测点。之后从该检测点继续服务,容许新事务构建在其一致状态上。并且,失败停止的事务将遗失。这些错误恢复被称为向后错误恢复,由于软件状态被回滚到过去的无错误点。
网路异常,图片未能展示
图2:检测点回滚场景
简单的检测点有自己危险的单点故障。在拍摄检测点本身的快照过程中可能会出现故障。但有一种解决方案,有时称为检测点回滚。如图2所示。在该图中,省略号表示通过队列发送消息来彼此通讯的软件顾客端和软件服务器。单个事务可能包括从顾客端到服务器的许多恳求消息,以及从服务器到顾客端的许多响应消息。在事务处理期间,数据在服务器内被更改。在事务结束时,应在右边显示的两个永久性大容量储存设备中的每一个上记录一组一致的数据。应连同数据一起记录交易序列号。假如稍后测量到错误而且服务器已停止,则可以重新启动此服务器(或启动副本服务器)。作为启动恢复过程的一部份,将检测两个大容量储存设备上的事务序列号。服务器数据将从包含最高序列号的设备中恢复。(另一个大容量储存设备可能包含较低的序列号,由于故障发生在该设备的检测点期间。)
进程对
这些检测点设计模式的一个限制是故障后的恢复可能须要很长时间。启动或重新启动服务器可能须要大量处理,也可能须要将数据恢复回检测点。“热备份”服务器直接使用其自身的永久性大容量储存设备,可以推动恢复速率。这些设计模式称为过程对;如图3所示。
网路异常,图片未能展示
图3:流程对
在这儿,我们看见坐落图中心的主服务器的工作情况与后面的检测点场景中的工作情况十分相像。顾客端直接使用此主服务器。每每主服务器成功完成整个事务时,它都会将有关其新的一致状态的信息传递给备份服务器(右边)。主服务器和备份服务器都将数据记录在其永久性大容量储存设备中。通过这些方法,备份服务器可以随时了解已完成的事务。当主服务器启动并可供顾客端使用时,它会定期向备份服务器发送脉搏消息。这种脉搏消息可以与一些检测点消息组合。假如备份服务器测量到脉搏消息流已停止,则它晓得主服务器已停止或不可用,但是它将很快接管新的主服务器。
当顾客端、主服务器和备份服务器都在不同的处理器或模块上时,以及当它们都在一个处理器上时,这些设计模式可以工作。
虽然过程对设计模式十分复杂,但仍存在一些问题。诸如,检测点消息可能会遗失或无序抵达备份服务器。或则,假如主服务器是化学设备的控制器,但是在操作过程中发生故障,则可能会出现问题。备份服务器在接管时可能不晓得怎么完成操作,由于它不晓得主服务器在发生故障之前走了多远。(比如:当发生故障时,主服务器已将核反应堆的石墨棒联通了所需的30cm。)
同样,在流程对设计模式中,当主服务器发生故障时正在进行的事务很可能在执行过程中遗失或遗弃。备份服务器将以主服务器在失败之前向其报告的先前完成事务的状态进行接管。
恢复块
动态软件冗余的另一种设计模式称为恢复块。它基于检测点,但它降低了对软件处理结果的初验测试。您须要像N版本编程一样打算许多处理数据的取代方式,但您并没有为每位事务运行所有处理取代方式。相反,您选择一种处理数据的方式作为主要取代方式,并首先尝试仅使用主要取代方式的处理来执行事务。在主处理结束时,运行初验测试。假如通过了初验测试,你就完成了。假如初验测试失败,则继续尝试下一个代替处理,如图4所示。
网路异常,图片未能展示
图4:恢复块
如图所示,在首次步入恢复块之前,必须执行检测点操作。每次初验测试失败后,软件必须回滚到检测点状态。初验测试是在尝试的每位处理备选方案以后进行的。以这些方法,在处理备选方案成功交付通过初验测试的结果之前,将运行处理备选方案。这种“良好”输出构成了恢复块的最终结果。
前向错误恢复
检测点回滚、进程对和恢复块都是执行向后错误恢复的方式。大多数动态软件容错是使用反向错误恢复来完成的,但正向错误恢复是另一种选择。它的主要思想是从错误状态继续,并进行纠正,以清除损坏状态。前向错误恢复取决于确切的损伤评估,一般是系统特定的。前向错误恢复的一个反例是异常处理,它在检查到问题时将控制权传递给专门的异常处理软件,而不是回滚并从原先的检测点状态继续。
前向错误恢复的一种设计模式称为取代处理。当一个事务有两个(或多个)处理备选方案时,可以使用此方式,其中一个备选方案一般十分精确但估算复杂,另一个备选更简单且性能更高。假如主处理出现故障,则第二个备选方案可以用作测试和辅助结果提供程序。诸如,平方根算法可以是主要处理,表查找配准可以是其取代方式。一旦算法运行完毕,可以使用表查找配准来测试平方根算法结果的质量,并快速修补这种结果中的一些错误。
网路异常,图片未能展示
图5:客机飞行控制的代替处理
在图5中,我们看见两个数字飞行控制系统同时运行,以控制一架客机(波音777)。[2]图左侧的决策逻辑使用更简单的飞行控制系统的输出作为测试复杂的主飞行控制系统输出的标尺。假如初验测试失败,这么更简单的飞行控制系统的输出也可以作为失败的主要输出的代替。(向左的箭头表示代替处理的结果也可用于向主处理提供反馈。)
这样的设计模式容许将日常商业质量的硬件和软件用作真正高可用性系统的建立块,这种系统可以在无需人工干预的情况下实现“五个9”或更高的可用性。
DavidKalinsky是OSESystems的顾客教育经理。他是嵌入式软件技术的讲师和研讨会领导者。近些年来,David构建了软件工程方面的高科技培训项目,以开发实时和嵌入式系统。在此之前,他参与了许多嵌入式医疗和民航航天系统的设计。大卫拥有哈佛学院核化学学博士学位。可以在联系到他。
Tags
本文: