4. 可用性
文章目录
4. 第4章 可用性
技术并不总是既完美又可靠。
现实可能恰恰相反!—Jean-Michel Jarre 让-米歇尔·雅尔
可用性是指软件的一种特性,即它在那里,并在您需要时准备好执行其任务。这是一个广义的概念,包括通常所说的可靠性(尽管它可能包括其他考虑因素,如定期维护导致的停机时间)。可用性建立在可靠性的概念之上,增加了恢复的概念,即当系统发生故障时,它会自行修复。正如我们将在本章中看到的,修复可以通过各种方式完成。
可用性还包括系统屏蔽或修复故障的能力,使其不会成为失效,从而确保累积服务中断期在指定的时间间隔内不会超过所需值。该定义包含可靠性、鲁棒性和任何其他涉及不可接受失效概念的质量属性的概念。
失效是指系统与其规范的偏差,这种偏差在外部可见。确定失效已经发生需要环境中的一些外部观察者。
失效的原因称为故障(fault)。故障可以是所考虑系统的内部故障,也可以是外部故障。故障发生和失效发生之间的中间状态称为错误。故障可以预防、容忍、消除或预测。通过这些操作,系统对故障具有“弹性”。我们关注的领域包括如何检测系统故障、系统故障发生的频率、故障发生时会发生什么、允许系统停止运行多长时间、故障或失效何时可以安全发生、如何预防故障或失效以及失效发生时需要什么样的通知。
可用性与信息安全性密切相关,但与其有明显不同。拒绝服务攻击被明确设计为使系统失败,即,使其不可用。可用性也与性能密切相关,因为可能很难判断系统何时发生故障,何时只是反应极其缓慢。最后,可用性与安全性密切相关,安全性涉及防止系统进入危险状态,并在进入危险状态时恢复或限制损坏。
构建高可用性容错系统中要求最高的任务之一是了解运行过程中可能出现的失效的性质。一旦理解了这些,就可以在系统中设计缓解策略。
由于用户可以观察到失效,因此修复时间是不再观察到失效的时间。这可能是用户响应时间的难以察觉的延迟,也可能是某人飞往安第斯山脉的偏远地区修理采矿机械所需的时间(正如负责修理矿机发动机中的软件的人向我们讲述的那样)。“可观察性”的概念在这里至关重要:如果一个失效本来可以被观察到,那么它就是一个失效,无论它是否被实际观察到。
此外,我们经常关注失效发生时剩余的能力水平 —— 降级的操作模式。
区分故障和失效使我们能够讨论修复策略。如果执行了包含故障的代码,但系统能够从故障中恢复,而与其他指定的行为没有任何可观察到的偏差,则我们说没有发生失效。
系统的可用性可以衡量为,它在指定的时间间隔内、在所需范围内提供指定服务的概率。一个众所周知的表达式用于派生稳态可用性(来自硬件世界):
MTBF / (MTBF + MTTR)
其中 MTBF 是指失效之间的平均时间(mean time between failures),MTTR 是指平均修复时间(mean time to repair)。在软件世界中,这个公式应该被解释为在考虑可用性时,你应该考虑什么会使你的系统失败,发生这种事件的可能性有多大,以及修复它需要多少时间。
通过此公式,可以计算概率并声明“系统表现出 99.999% 的可用性”或“系统在需要时无法运行的概率为 0.001%。在计算可用性时,不应考虑计划的停机时间(当系统特意停止服务时),因为当时系统被视为“不需要”;当然,这取决于系统的特定要求,这些要求通常写在服务级别协议(SLA)中。这可能会导致看似奇怪的情况,即系统关闭并且用户正在等待它,但因为停机时间是计划的,因此不计入任何可用性要求。
检测到的故障可以在报告和修复之前进行分类。此分类通常基于故障的严重性(严重、主要或次要)和服务影响(影响服务或不影响服务)。它为系统操作员提供及时准确的系统状态,并允许采用适当的修复策略。修复策略可以是自动化的,也可以是需要手动干预的。
如前所述,系统或服务预期的可用性通常表示为 SLA。SLA 指定保证的可用性级别,通常指定供应商在违反 SLA 时将遭受的处罚。例如,Amazon 为其 EC2 云服务提供以下 SLA:
AWS 将尽商业上合理的努力,在任何月度计费周期内,每个 AWS 区域的月度正常运行时间百分比至少为 99.99%,提供每项包含的服务(“服务承诺”)。如果任何包含的服务不符合服务承诺,您将有资格获得如下所述的服务积分。
表4.1 提供了系统可用性需求的示例以及可接受的系统停机时间的相关阈值,在 90 天和一年的观察期内测量。术语“高可用性”通常是指以 99.999%(“5 个 9”)或更高的可用性为目标的设计。如前所述,只有计划外停机才会归为系统停机。
表 4.1 系统可用性需求
可用性 | 停机时间/90 天 | 停机时间/年 |
---|---|---|
99.0% | 21 小时, 36 分 | 3 天, 15.6 小时 |
99.9% | 2 小时, 10 分 | 8 小时, 45 分. |
99.99% | 12 分, 58 秒 | 52 分, 34 秒 |
99.999% | 1 分, 18 秒 | 5 分, 15 秒 |
99.9999% | 8 秒 | 32 秒 |
4.1. 可用性一般场景
现在,我们可以描述可用性一般场景的各个部分,如 表 4.2 中所述。
表 4.2 可用性一般场景
场景部分 | 描述 | 可能的值 |
---|---|---|
来源 | 这指定了故障的来源。 | 内部/外部:人员、硬件、软件、物理基础设施、物理环境 |
触发事件 | 可用性场景的触发事件是故障。 | 故障:遗漏、崩溃、计时不正确、响应不正确 |
工件 | 这指定系统的哪些部分负责并受故障影响。 | 系统环境中的处理器、通信通道、存储、进程、受影响的工件 |
环境 | 我们可能不仅对系统在其“正常”环境中的行为感兴趣,而且对系统在已经从故障中恢复时的行为感兴趣。 | 正常操作、启动、关机、修复模式、降级操作、过载操作 |
响应 | 最常见的响应是防止故障成为失效,但其他响应也可能很重要,例如通知人员或记录故障以供以后分析。本节指定所需的系统响应。 | 防止故障变成失效
|
响应测量 | 我们可能会专注于一些可用性措施,具体取决于所提供服务的关键程度。 |
|
从 表 4.2 中的一般场景派生出的具体可用性场景示例显示在 图 4.1 中。场景如下:服务器场中的服务器在正常操作期间出现故障,系统通知操作员并继续运行,没有停机。
图 4.1 具体可用性场景示例
4.2. 可用性策略
当系统不再提供与其规范一致的服务并且系统参与者可以观察到此失效时,就会发生失效。故障(或故障组合)有可能导致失效。反过来,可用性策略旨在使系统能够防止或忍受系统故障,以便系统提供的服务始终符合其规范。我们在本节中讨论的策略将防止故障成为失效,或者至少限制故障的影响并使修复成为可能,如 图4.2 所示。
图 4.2 可用性策略的目标
可用性策略具有以下三个目的之一:故障检测、故障恢复或故障预防。可用性的策略如 图4.3 所示。这些策略通常由软件基础设施(如中间件包)提供,因此作为架构师,您的工作可能是选择和评估(而不是实施)正确的可用性策略和正确的策略组合。
图 4.3 可用性策略
故障检测(Detect Faults)
在任何系统对故障采取措施之前,必须检测或预测故障的存在。此类别中的策略包括:
-
监控(Monitor):此组件用于监控系统其他各个部分的运行状况状态:处理器、进程、I/O、内存等。系统监控可以检测网络或其他共享资源中的失效或拥塞,例如拒绝服务攻击。它使用此类别中的其他策略来协调软件,以检测失灵的组件。例如,系统监控可以启动自检(self-tests),或者成为检测错误的*时间戳(timestamps)或丢失心跳(heartbeats)*的组件。1
-
ping/echo:在这种策略中,异步请求/响应消息对在节点之间交换;它用于确定通过关联网络路径的可达性和往返延迟。此外,echo指示 ping 的组件处于活动状态。ping 通常由系统监控发送。Ping/echo需要设置时间阈值;此阈值告诉 ping 组件在认为 ping 组件失败(“超时”)之前等待echo的时间。ping/echo 的标准实现可用于通过互联网协议 (IP) 互连的节点。
-
心跳(Heartbeat): 此故障检测机制采用系统监控和被监控进程之间的定期消息交换。检测信号的一个特殊情况是,被监控的进程定期重置其监控中的看门狗计时器,以防止其过期,从而发出故障信号。对于关注可伸缩性的系统,可以通过将检测信号消息搭载到正在交换的其他控制消息上来减少传输和处理开销。检测信号和 ping/echo 之间的区别在于谁负责启动运行状况检查 — 监控还是组件本身。
-
时间戳(Timestamp): 此策略用于检测不正确的事件序列,主要是在分布式消息传递系统中。可以通过在事件发生后立即将本地时钟的状态分配给事件来建立事件的时间戳。序列号也可用于此目的,因为分布式系统中的时间戳在不同处理器之间可能不一致。参见 Chapter 17,更全面地讨论分布式系统中的时间主题。
-
状态监控(Condition monitoring):这种策略涉及检查进程或设备中的条件,或验证设计过程中的假设。通过监控条件,此策略可防止系统产生错误行为。计算校验和是这种策略的一个常见示例。但是,监控本身必须简单(理想情况下,可证明是正确的),以确保它不会引入新的软件错误。
-
健全性检查(Sanity checking):此策略检查组件的特定操作或输出的有效性或合理性。它通常基于对内部设计、系统状态或受审查信息性质的了解。它最常用于接口,以检查特定的信息流。
-
投票(Voting):投票涉及比较来自多个来源的计算结果,这些结果应该产生相同的结果,如果不是,则决定使用哪些结果。这种策略在很大程度上取决于投票逻辑,投票逻辑通常被实现为一个简单的、经过严格审查和测试的单例,因此出错的可能性很低。投票还严重取决于有多个来源进行评估。典型的方案包括:
-
复制(Replication):是最简单的投票形式;在这里,组件是彼此的精确克隆。拥有相同组件的多个副本可以有效地防止硬件的随机失效,但不能防止硬件或软件中的设计或实现错误,因为这种策略中没有嵌入任何形式的多样性。
-
功能冗余(Functional redundancy):相比之下,其旨在通过实现设计多样性来解决硬件或软件组件中的共模失效(副本同时表现出相同的故障,因为它们共享相同的实现)问题。这种策略试图通过增加冗余的多样性来处理系统性的设计故障。在给定相同输入的情况下,功能冗余组件的输出应相同。功能冗余策略仍然容易受到规范错误的影响,当然,开发和验证功能副本的成本会更高。
-
分析冗余(Analytic redundancy):不仅允许组件私有端之间的多样性,还允许组件输入和输出之间的多样性。此策略旨在通过使用单独的需求规范来容忍规范错误。在嵌入式系统中,当某些输入源有时可能不可用时,分析冗余会有所帮助。例如,航空电子程序有多种方法来计算飞机高度,例如使用气压、雷达高度计以及几何方式使用地面前方点的直线距离和俯视角。与分析冗余一起使用的投票机制需要比仅仅让多数统治或计算简单的平均值更加复杂。它可能必须了解哪些传感器当前可靠(或不可靠),并且可能会要求它通过随着时间的推移混合和平滑单个值来产生比任何单个组件更高的精确度值。
-
-
异常检测(Exception detection):此策略侧重于检测改变正常执行流程的系统状况。可以进一步细化如下:
-
系统异常(System exceptions):将根据所使用的处理器硬件架构而有所不同。它们包括除零、总线和地址故障、非法程序指令等故障。
-
参数围栏(parameter fence) 策略包含紧跟在对象的任何可变长度参数之后的已知数据模式(例如0xDEADBEEF)。这允许运行时检测覆盖为对象的可变长度参数分配的内存。
-
参数类型(Parameter typing) 使用基类,该基类定义添加、查找和迭代类型-长度-值 (TLV) 格式的消息参数的函数。派生类使用基类函数来提供用于生成和分析消息的函数。使用参数类型可确保消息的发送方和接收方就内容类型达成一致,并检测不一致的情况。
-
超时(Timeout) 是一种策略,当组件检测到它或其他组件未能满足其时序约束时,会引发异常。例如,如果等待时间超过特定值,等待来自另一个组件响应的组件可能会引发异常。
-
-
自检(Self-test):组件(或者更可能的是整个子系统)可以运行程序来测试自身是否正确操作。自检过程可以由组件本身启动,也可以由系统监控不定时调用。这些可能涉及使用状态监测中的一些技术,例如校验和。
故障恢复(Recover from Faults )
从故障中恢复(Recover from faults) 策略被细化为准备和修复策略以及重新引入策略。后者关注的是将故障(但已修复)的组件重新引入正常运行。
准备和修复(Preparation and repair) 策略基于重试计算或引入冗余的各种组合:
-
冗余备件(Redundant spare):此策略是指在主组件发生故障时,一个或多个重复组件可以介入并接管工作的配置。此策略是热备盘、温备盘和冷备盘模式的核心,它们的主要区别在于备份组件在接管时的最新程度。
-
回滚(Rollback):回滚允许系统在检测到失效时恢复到先前已知的良好状态(称为“回滚线”)— 回滚时间。一旦达到良好状态,就可以继续执行。此策略通常与事务策略和冗余备件策略结合使用,以便在发生回滚后,失败组件的备用版本将提升为活动状态。回滚取决于以前良好状态(检查点)的副本可用于正在回滚的组件。检查点可以存储在固定位置并定期更新,也可以在处理过程中方便或重要的时间(例如在复杂操作完成时)进行更新。
-
异常处理(Exception handling):一旦检测到异常,系统将以某种方式处理它。它能做的最简单的事情就是崩溃——但是,当然,从可用性、易用性、可测试性和简单的良好意愿的角度来看,这是一个糟糕的主意。还有更多富有成效的可能性。用于异常处理的机制在很大程度上取决于所使用的编程环境,范围从简单的函数返回代码(错误代码)到使用异常类,这些异常类包含有助于故障关联的信息,例如异常的名称、异常的来源和异常的原因。然后,软件可以使用此信息来屏蔽或修复故障。
-
软件升级(Software upgrade):此策略的目标是以不影响服务的方式实现对可执行代码映像的服务中升级。策略包括以下内容:
-
功能补丁(Function patch):这种补丁用于过程编程,它使用增量链接器/加载器将更新的软件功能存储到目标内存的预分配段中。新版本的软件功能将使用已弃用功能的入口点和出口点。
-
类补丁(Class patch):这种升级适用于执行面向对象代码的目标,其中类定义包括一个后门机制,该机制允许运行时添加成员数据和函数。
-
无中断服务中软件升级 (Hitless in-service software upgrade,ISSU)。这利用冗余备件策略来实现对软件和相关架构的不影响服务的升级。
在实践中,函数补丁和类补丁用于提供错误修复,而无中断的 ISSU 用于提供新的特性和功能。
-
-
重试(Retry):重试策略假定导致失效的故障是暂时性的,并且重试操作可能会导致成功。它用于网络和服务器农场中,其中失效是预期和常见的。在声明永久失效之前,应限制尝试的重试次数。
-
忽略错误行为(Ignore faulty behavior):当我们确定从特定来源发送的消息是虚假消息时,此策略要求忽略这些消息。例如,我们希望忽略传感器实时失效发出的消息。
-
优雅降级(Graceful degradation):这种策略在组件失效时保持最关键的系统功能,同时放弃不太重要的功能。这是在单个组件失效时正常降低系统功能而不是导致整个系统失效的情况下完成的。
-
重新配置(Reconfiguration):重新配置尝试通过将职责重新分配给(可能受限的)保持正常运行的资源或组件,同时保持尽可能多的功能,从而从失效中恢复。
*重新引入(Reintroduction)*是指失败组件在修复后重新引入。重新引入策略包括以下内容:
-
影子(Shadow):此策略是指在将组件恢复为活动角色之前,在预定义的持续时间内以“影子模式”运行以前发生故障或服务中的升级组件。在此期间,可以监控其行为的正确性,并且可以增量地重新填充其状态。
-
状态重新同步(State resynchronization):此重新引入策略是冗余备件策略的合作伙伴。当与主动冗余(冗余备件策略的一种版本)一起使用时,状态重新同步是有机发生的,因为活动和备用组件各自并行接收和处理相同的输入。实际上,会定期比较活动和备用组件的状态,以确保同步。这种比较可以基于循环冗余校验(CRC)计算(校验和(checksum)),或者对于提供安全关键服务的系统,可以基于消息摘要计算(单向哈希函数)。当与冗余备件策略的被动冗余版本一起使用时,状态重新同步仅基于从活动组件传输到备用组件的定期状态信息,通常通过检查点传输。
-
升级重启(Escalating restart):此重新引入策略允许系统通过改变重新启动的组件的粒度并最大程度地减少服务影响级别来从故障中恢复。例如,考虑一个支持四个级别的重新启动的系统,编号为 0–3。最低级别的重启(级别 0)对服务的影响最小,并采用被动冗余(温备),其中故障组件的所有子线程都将被终止并重新创建。这样,仅释放并重新初始化与子线程关联的数据。下一级重新启动(级别 1)释放并重新初始化所有未受保护的内存;受保护的内存保持不变。下一级重新启动(级别 2)释放并重新初始化所有内存(包括受保护和未受保护的内存),强制所有应用程序重新加载并重新初始化。重新启动的最后一级(级别 3)涉及完全重新加载和重新初始化可执行映像和关联的数据段。对升级重启策略的支持对于正常降级的概念特别有用,在正常降级概念中,系统能够降低其提供的服务,同时保持对任务关键型或安全关键型应用程序的支持。
-
不间断转发(Nonstop forwarding): 此概念起源于路由器设计,并假定功能分为两部分:监督或控制平面(管理连接和路由信息)和数据平面(执行将数据包从发送方路由到接收方的实际工作)。如果路由器遇到活动管理引擎失效,它可以继续沿已知路由(与相邻路由器)转发数据包,同时恢复和验证路由协议信息。重新启动控制平面时,它将实现“平稳重启”,即使数据平面继续运行,也会以增量方式重建其路由协议数据库。
故障预防(Prevent Faults)
与其检测故障然后尝试从中恢复,不如你的系统首先可以防止它们发生呢?虽然听起来好像需要某种程度的千里眼,但事实证明,在许多情况下,可以做到这一点。2
-
从服务中删除(Removal from service):此策略是指暂时将系统组件置于停止服务状态,以减轻潜在的系统失效。例如,系统的某个组件可能会停止服务并重置以清除潜在故障(例如内存泄漏、碎片或未受保护的缓存中的软错误),然后再累积故障达到影响服务的级别,从而导致系统失效。这种策略的其他术语是软件复兴(software rejuvenation)和治疗性重启(therapeutic reboot)。 如果您每晚重新启动计算机,则您正在练习从服务中删除。
-
事务(Transactions):面向高可用性服务的系统利用事务语义来确保分布式组件之间交换的异步消息是原子的、一致的、隔离的和持久的,这些属性统称为“ACID 属性”。交易策略最常见的实现是“两阶段提交”(2PC)协议。此策略可防止由两个进程尝试同时更新同一数据项而导致的竞争条件。
-
预测模型(Predictive model):当与监控结合使用时,预测模型用于监控系统进程的运行健康状态,以确保系统在其标称操作参数内运行,并在系统接近临界阈值时采取纠正措施。监控的运行指标用于预测故障的发生;示例包括会话建立率(在 HTTP 服务器中)、阈值交叉(监控某些受约束的共享资源的高水位线和低水位线)、进程状态统计信息(例如,服务中、服务中断、维护中、空闲)和消息队列长度统计信息。
-
异常预防(Exception prevention):此策略是指用于防止系统异常发生的技术。前面讨论了异常类的使用,它允许系统透明地从系统异常中恢复。异常预防的其他示例包括纠错代码(用于电信)、抽象数据类型(如智能指针)以及使用包装器来防止故障(如悬空指针或信号量访问冲突)。智能指针通过对指针进行边界检查来防止异常,并确保在没有数据引用资源时自动取消分配资源,从而避免资源泄漏。
-
增加能力集(Increase competence set): 程序的能力集是它“有能力”运行的状态集。例如,分母为零的状态超出了大多数除法计划的能力集。当一个组件引发异常时,它表明它发现自己超出了其能力范围;从本质上讲,它不知道该怎么做,正在认输。提高组件的能力集意味着将其设计为处理更多情况(故障),作为其正常运行的一部分。例如,假定其有权访问共享资源的组件在发现访问被阻止时可能会引发异常。另一个组件可能只是等待访问或立即返回,并指示它将在下次具有访问权限时自行完成其操作。在此示例中,第二个组件比第一个组件具有更大的能力集。
4.3. 基于策略的可用性调查表
基于 4.2节 中描述的策略,我们可以创建一组受可用性策略启发的问题,如 表 4.3 所示。为了大致了解为支持可用性而做出的架构选择,分析师会询问每个问题并将回答记录在表中。然后,可以将这些问题的回答作为进一步活动的重点:文档调查、代码或其他工件分析、代码逆向工程等。
表4.3 基于策略的可用性调查表
策略组 | 策略问题 | 支持?(是/否) | 风险 | 设计决策和位置 | 原因和假设 |
---|---|---|---|---|---|
故障检测 | 系统是否使用 ping/echo 来检测组件或连接失效或网络拥塞? | ||||
系统是否使用组件来监控系统其他部分的运行状况状态?系统监控可以检测网络或其他共享资源中的失效或拥塞,例如拒绝服务攻击。 | |||||
系统是否使用心跳(系统监控和进程之间的定期消息交换)来检测组件或连接失效或网络拥塞? | |||||
系统是否使用时间戳来检测分布式系统中不正确的事件序列? | |||||
系统是否使用投票来检查复制的组件是否产生相同的结果?复制的组件可以是相同的副本、功能冗余或分析冗余。 | |||||
系统是否使用异常检测来检测改变正常执行流程的系统条件(例如,系统异常、参数围栏、参数类型、超时)? | |||||
系统是否可以执行自检来测试自身是否正确操作? | |||||
故障恢复(准备和修复) | 系统是否使用冗余备件?组件的角色是固定的还是备用的,还是在出现故障时发生变化?切换机制是什么?切换的触发因素是什么?备件履行职责需要多长时间? | ||||
系统是否采用异常处理来处理故障?通常,处理涉及报告、纠正或屏蔽故障。 | |||||
系统是否采用回滚,以便在发生故障时可以恢复到以前保存的良好状态(“回滚行”)? | |||||
系统能否以不影响服务的方式对可执行代码映像执行服务中软件升级? | |||||
在组件或连接失效可能是暂时性的情况下,系统是否系统性地“重试”? | |||||
系统是否可以简单地忽略错误行为(例如,在确定消息是虚假消息时忽略这些消息)? | |||||
系统是否具有在资源受到损害时降级的策略,在组件失效时保持最关键的系统功能,并丢弃不太重要的功能? | |||||
系统是否具有一致的策略和机制,用于在发生失效后进行重新配置,将职责重新分配给剩余运行的资源,同时保持尽可能多的功能? | |||||
故障恢复(重新引入) | 在将组件恢复为活动角色之前,系统是否可以在预定义的时间内以“影子模式”运行以前发生故障或服务中的升级组件? | ||||
如果系统使用主动或被动冗余,是否还使用状态重新同步将状态信息从活动组件发送到备用组件? | |||||
系统是否采用升级重启通过改变重新启动的组件的粒度并最小化受影响的服务级别来从故障中恢复? | |||||
系统的消息处理和路由部分是否可以采用“不间断转发”,其中功能分为监控平面和数据平面? | |||||
故障预防 | 系统是否可以从服务中删除组件,暂时将系统组件置于停止服务状态,以便预防潜在的系统失效? | ||||
系统是否采用事务 - 捆绑状态更新,以便分布式组件之间交换的异步消息原子,一致,隔离和持久? | |||||
系统是否使用预测模型来监控组件的运行状况状态,以确保系统在标称参数范围内运行?当检测到预测未来可能故障的条件时,模型将启动纠正措施。 |
4.4. 可用性模式
本节介绍一些最重要的可用性架构模式。
前三种模式都以冗余备件策略为中心,将描述为一组。它们的主要区别在于备份组件的状态与活动组件的状态匹配程度。(当组件是无状态的时,会出现一种特殊情况,在这种情况下,前两种模式将变得相同。
-
主动冗余(热备)(Active redundancy (hot spare)):对于有状态组件,这是指保护组3中的所有节点(活动或冗余备用)并行接收和处理相同输入的配置,从而允许冗余备件与活动节点保持同步状态。由于冗余备件具有与活动组件有相同的状态,因此它可以在几毫秒内接管失败组件。一个主动节点和一个冗余备用节点的简单情况通常称为一加一冗余。主动冗余还可用于设施保护,其中活动和备用网络链路用于确保高可用性网络连接。
-
被动冗余(温备)(Passive redundancy (warm spare)):对于有状态组件,这是指只有保护组的活动成员处理输入流量的配置。他们的职责之一是为冗余备件提供定期状态更新。由于冗余备件维护的状态仅与保护组中主动节点的状态松散耦合(耦合松散程度是状态更新周期的函数),因此冗余节点称为温备。被动冗余提供了一种解决方案,可在可用性更高但计算密集度更高(且成本更高)的主动冗余模式与可用性较低但复杂度低得多的冷备用模式(也便宜得多)之间实现平衡。
-
备用(冷备)(Spare (cold spare)):冷备是指冗余备件在发生故障切换之前保持停止服务的配置,此时在冗余备件投入使用之前,会在冗余备件上启动开机复位4过程。由于其恢复性能较差,因此平均修复时间较长,所以此模式不适合具有高可用性要求的系统。
好处:
- 冗余备件的好处是系统在发生失效时仅短暂延迟后仍能继续正常运行。另一种方法是系统停止正常运行或完全停止运行,直到修复失败组件。此修复可能需要数小时或数天。
代价:
-
与这些模式中的任何一种的代价都是提供备件所产生的额外成本和复杂性。
-
这三种备选方案之间的权衡是从失效中恢复的时间与使备用设备保持最新所需的运行时成本。例如,热备的成本最高,但恢复时间最快。
可用性的其他模式包括以下内容。
-
三重模块冗余 (TMR)(Triple modular redundancy (TMR)):这种广泛使用的投票策略实施采用了三个组件来做同样的事情。每个组件接收相同的输入并将其输出转发到投票逻辑,该逻辑检测三个输出状态之间的任何不一致。面对不一致,投票会报告了一个故障。它还必须决定使用哪个输出,并且此模式的不同实例使用不同的决策规则。典型的选择是少数服从多数或选择不同输出的某种计算平均值。
当然,这种模式的其他版本也有可能使用 5 个、19 个或 53 个冗余组件。但是,在大多数情况下,3个组件足以确保可靠的结果。
好处:
- TMR 易于理解和实施。它容易地独立于可能导致不同结果的因素,并且只关心做出合理的选择,以便系统可以继续运行。
代价:
- 在提高复制级别(这会增加成本)和由此产生的可用性之间需要权衡。在采用 TMR 的系统中,两个或多个组件发生故障的统计可能性微乎其微,三个组件代表了可用性和成本之间的最佳平衡点。
-
断路开关(Circuit breaker):常用的可用性策略是重试。如果在调用服务时发生超时或故障,调用程序只需一次又一次地尝试。断路开关可防止调用者尝试无数次,等待永远不会出现的响应。这样,当它认为系统正在处理故障时,它会中断无休止的重试循环。这是系统开始处理故障的信号。在断路“复位”之前,后续调用将立即返回,而不会传递服务请求。
好处:
-
此模式可以从各个组件中删除有关在声明失效之前允许重试次数的策略。
-
在最坏的情况下,无休止的无果重试将使调用组件与失败的调用组件一样无用。此问题在分布式系统中尤其严重,在分布式系统中,您可能会有许多调用方调用无响应的组件,并实际上自己停止服务,从而导致整个系统级联失效。断路开关与侦听它并开始恢复过程的软件一起防止该问题。
代价:
- 选择超时(或重试)值时必须小心。如果超时太长,则会增加不必要的延迟。但是,如果超时太短,则断路开关将在不需要时跳闸(一种“误报”),这可能会降低这些服务的可用性和性能。
常用的其他可用性模式包括:
-
-
进程对(Process pairs)。此模式采用检查点和回滚。如果发生失效,备份已执行检查点操作,并(如有必要)回滚到安全状态,因此已准备好在发生失效时接管。
-
前向错误恢复(Forward error recovery)。这种模式提供了一种通过向前移动到理想状态来摆脱不良状态的方法。这通常依赖于内置的纠错功能(如数据冗余),以便可以纠正错误,而无需回退到以前的状态或重试。正向错误恢复查找一个安全的、可能已降级的状态,操作可以从该状态向前推进。
4.5. 扩展阅读
可用性模式:
- 您可以在 [Hanmer 13] 中阅读有关容错模式的信息。
可用性的一般策略:
-
本章中对一些可用性策略的更详细讨论在 [Scott 09] 中给出。这是本章大部分材料的来源。
-
互联网工程任务组已经颁布了许多支持可用性策略的标准。这些标准包括不间断转发 [IETF 2004],Ping/Echo(ICMP [IETF 1981]或ICMPv6 [RFC 2006b] 回声请求/响应)和MPLS (LSP Ping)网络[IETF 2006a]。
可用性策略 — 故障检测(fault detection):
-
三重模块冗余(TMR)由里昂在1960年代初由里昂[Lyons 62]开发。
-
投票策略中的故障检测基于冯·诺依曼对自动机理论的基本贡献,他展示了如何从不可靠的组件构建具有规定可靠性的系统[冯·诺依曼 56]。
可用性策略 — 故障恢复(fault recovery):
-
基于标准的主动冗余实现存在于七层OSI(开放系统互连)模型[Bellcore 98,99; Telcordia 00] 的物理层保护网络链路(即设施)和网络/链路层 [IETF 2005]。
-
[Nygard 18] 中给出了系统如何通过使用(退化)而降级的一些示例。
-
关于参数类型的论文堆积如山,但是[Utas 05]在可用性的背景中写了它(与错误预防相反,它通常的背景)。[Utas 05] 也写过关于升级重启的文章。
-
硬件工程师经常使用准备和维修策略。示例包括错误检测和纠正 (EDAC) 编码、前向纠错 (FEC) 和临时冗余。EDAC编码通常用于保护高可用性分布式实时嵌入式系统中的控制存储器结构[Hamming 80]。相反,FEC 编码通常用于从外部网络链路中发生的物理层错误中恢复 [Morelos-Zaragoza 06]。时间冗余涉及以超过任何瞬态脉冲的脉冲宽度的时间间隔对空间冗余时钟或数据线进行采样,然后投票排除检测到的任何缺陷[Mavis 02]。
可用性策略 — 故障预防(fault prevention):
灾难恢复(Disaster recovery):
- 灾难是摧毁整个数据中心的事件,如地震、洪水或飓风。美国国家标准与技术研究院 (NIST) 确定了在发生灾难时应考虑的八种不同类型的计划,请参阅 NIST 特别出版物 800-34 的 第 2.2 节,联邦信息系统应急计划指南,https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-34r1.pdf。
4.6. 问题讨论
1. 使用常规方案中每个可能的响应编写一组具体的可用性方案。
2. 为(假设的)无人驾驶汽车的软件编写一个具体的可用性方案。
3. 为Microsoft Word 等程序编写具体的可用性方案。
4. 冗余是实现高可用性的关键策略。查看本章中介绍的模式和策略,并确定其中有多少利用某种形式的冗余,有多少没有。
5. 可用性如何与可修改性和可部署性进行权衡?您将如何对需要具有 7x24 可用性的系统进行更改(即,永远没有计划或计划外停机时间)?
6. 考虑故障检测策略(ping/echo、检测信号、系统监控、投票和异常检测)。使用这些策略对性能有何影响?
7. 负载均衡器在检测到实例失效时会使用哪些策略(请参阅 第 17 章)?
8. 查找恢复点目标 (RPO) 和恢复时间目标 (RTO),并说明在使用回滚策略时如何使用它们来设置检查点间隔。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!