2.4.2 故障模型
在分布式系统中,进程和通信通道都有可能出故障,即它们可能偏离被认为是正确或所期望的行为。故障模型定义了故障可能发生的方式,以便理解故障所产生的影响。Hadzilacos和Toueg[1994]提供了一种分类法,用于区分进程故障和通信通道故障。这些故障将分别在下面的“遗漏故障”、“随机故障”和“时序故障”部分介绍。
本书将贯穿使用故障模型。例如:
- 第4章给出数据报和流通信的Java接口,它们分别提供不同程度的可靠性。
- 第5章给出支持RMI的请求-应答协议。它的故障特征取决于进程和通信通道两者的故障特征。该协议能用数据报或流通信实现。可根据实现的简单性、性能和可靠性作出决定。
- 第17章给出事务的两阶段的提交协议。它用于在面对进程和通信通道的确定性故障时完成事务。
遗漏故障 遗漏故障类错误指的是进程或通信通道不能完成它应该做的动作。
进程遗漏故障:进程主要的遗漏故障是崩溃。当我们说进程崩溃了,意为进程停止了,将不再执行程序的任何步骤。能在故障面前存活的服务,如果假设该服务所依赖的服务能干净利落地崩溃,即进程仍能正确运行或者停止运行,那么它的设计能被简化。其他进程通过下列事实能检测到这种进程崩溃:这个进程一再地不能对调用消息进行应答。然而,这种崩溃检测的方法依赖超时的使用,即进程用一段固定时间等待某个事件的发生。在异步系统中,超时只能表明进程没有响应——它可能是崩溃了,也可能是执行速度慢,或者是消息还没有到达。
如果其他进程能确切检测到进程已经崩溃,那么这个进程崩溃称为故障-停止。在同步系统中,如果确保消息已被传递,而其他进程又没有响应时,进程使用超时来检测,那么就会产生故障-停止行为。例如,对于进程p和q,如果设计q应答来自p的消息,而且进程p在按p本地时钟度量的一个最大时间范围内没有收到进程q的应答,那么进程p可以得出结论:进程q出现了故障。下面的“故障检测”和“面对通信故障时达成协定的不可能性”部分说明在异步系统中检测故障的困难以及在故障面前达成协定的困难。
图2-14 进程和通道通信遗漏故障:考虑通信原语send和receive。进程p通过将消息m插入到它的外发消息缓冲区来执行send。通信通道将m传输到q的接收消息缓冲区。进程q通过将m从它的接收消息缓冲区取走并完成传递来执行receive(见图2-14)。通常由操作系统提供外发消息缓冲区和接收消息缓冲区。
如果通信通道不能将消息从p的外发消息缓冲区传递到q的接收消息缓冲区,那么它就产生了遗漏故障。这就是所谓的“丢失消息”,造成消息丢失的原因通常是在接收端或中间的网关上缺乏缓冲区空间,或因为网络传输错误(可由消息数据携带的校验和检测到)。Hadzilacos和Toueg[1994]把在发送进程和外发消息缓冲区之间的消息丢失称为发送遗漏故障;在接收消息缓冲区和接收进程之间的消息丢失称为接收遗漏故障;在两者之间的消息丢失称为通道遗漏故障。遗漏故障和随机故障的分类见图2-15。
故障检测 在Pepperland师驻扎在山顶的情况下(见“Pepperland协定”部分),假设敌军聚集足够的力量攻击任意一个扎营的师,那么任意一个师都可能失败。进一步假设,在没有被攻击的时候,各师定时地派出通信兵向对方报告自己的状态。在异步系统中,没有一个师能区别是对方被打败了还是通信兵跨越中间山谷的时间太长。在同步的Pepperland中,一个师通过应该定期出现的通信兵的缺席就能判断出另一个师是否被打败了。但是,另一个师可能在派出最后一个通信兵后就被打败了。
面对通信故障时达成协定的不可能性 我们一直假设Pepperland通信兵最终总能设法通过山谷,但现在要假设敌军会抓住通信兵,阻止他到达(我们还假设敌人不可能给通信兵“洗脑”,从而让他传达错误的消息)。红师和蓝师能发送消息使得他们能一致决定对敌军冲锋或投降吗?非常遗憾,正如Pepperland理论家Ringo大师证明的一样,在这样的环境中,两个师不能一致地决定做什么。为了了解这一点,假设其反面观点成立即两个师能执行达成一致的Pepperland协议。某一方提出“冲锋!”或“投降!”,协议使得双方同意这一方或另一方的动作。现在考虑在某一轮协议中发送的最后一个消息。携带消息的通信兵可能被敌军俘虏。不论消息到达与否,最后的结果必须一致。所以我们去掉它。现在我们对剩下消息中的最后一个应用同一论点。这个论点可再应用到那个消息,然后继续应用这个论点,最后我们将以没有要发送的消息结束!这表明如果通信兵被俘虏,就没有保证Pepperland师之间一致的协议存在。
故障可以按照它们的严重性分类。到现在为止,我们描述的所有故障是良性故障。在分布式系统中,大多数故障是良性的。良性故障包括遗漏故障以及时序故障和性能故障。
随机故障 术语随机故障或拜占庭故障用于描述可能出现的最坏的故障,此时可能发生任何类型的错误。例如,一个进程可能在数据项中设置了错误的值,或为响应一个调用返回一个错误的值。
进程的随机故障是指进程随机地省略要做的处理步骤或执行一些不需要的处理步骤。进程的随机故障不能通过查看进程是否应答调用来检测,因为它可能随机地遗漏应答。
通信通道也会出现随机故障。例如,消息内容可能被损坏或者传递不存在的消息,也可能多次传递实际的消息。通信通道的随机故障很少,因为通信软件能识别这类故障并拒绝出错的消息。例如,可用校验和来检测损坏的消息,消息序号可用于检测不存在和重复的消息。
时序故障 时序故障适用于同步分布式系统。在这样的系统中,对进程执行时间、消息传递时间和时钟漂移率均有限制。时序故障见图2-16的列表。这些故障中的任何一个均可导致在指定时间间隔内对客户没有响应。
故 障 类 型影 响 对 象描 述时钟进程进程的本地时钟超过了与实际时间的漂移率的范围性能进程进程超过了两个进程步之间的间隔范围性能通道消息传递花费了比规定的范围更长的时间
在异步分布式系统中,一个负载过重的服务器的响应时间可能很长,但我们不能说它有时序故障,因为它不提供任何保证。
实时操作系统是以提供时序保证为目的而设计的,但这种系统在设计上很复杂的,会要求冗余的硬件。大多数通用的操作系统(如UNIX)不能满足实时约束。
时序与有音频和视频通道的多媒体计算机的关系尤为密切。视频信息要求传输海量的数据。若要在传递视频信息时不出现时序故障,那么就要对操作系统和通信系统提出特殊的要求。
故障屏蔽 分布式系统中的每个组件通常是基于其他一组组件构造的。利用存在故障的组件构造可靠的服务是可能的。例如,保存有数据副本的多个服务器在其中一个服务器崩溃时能继续提供服务。了解组件的故障特征有利于在设计新服务时屏蔽它所依赖的组件的故障。一个服务通过隐藏故障或者将故障转换成一个更能接受的故障类型来屏蔽故障。对于后者,我们给出一个例子,校验和用于屏蔽损坏的消息,它有效地将随机故障转化为遗漏故障。第3章和第4章介绍通过使用将不能到达目的地的消息重传的协议可以隐藏遗漏故障。第18章将介绍利用复制进行故障屏蔽的方法。甚至进程崩溃也可以屏蔽,即通过替换崩溃进程并根据原进程存储在磁盘上的信息恢复内存来实现。
一对一通信的可靠性 虽然基本的通信通道可能出现前面描述的遗漏故障,但用它来构造一个能屏蔽某些故障的通信服务是可能的。
术语可靠通信可从下列有效性和完整性的角度来定义:
有效性:外发消息缓冲区中的任何消息最终能传递到接收消息缓冲区。
完整性:接收到的消息与发送的消息一致,没有消息被传递两次。
对完整性的威胁来自两个方面:
- 任何重发消息但不拒绝到达两次的消息的协议。要检测消息是否到达了两次,可以在协议中给消息附加序号。
- 心怀恶意的用户,他们可能插入伪造的消息、重放旧的消息或篡改消息。在面对这种攻击时为维护完整性要采取相应的安全措施。