我首次接触高可用性 (HA) 是在 20 世纪 80 年代,当时在从事商业对地同步通讯卫星方面的工作。为了让信号以可靠的方式通过卫星,平台的首要目标是 “指向(Pointing)”。指向 的意思是要求卫星(或卫星上的设备)朝向一些地面目标。当卫星丢失指向时,通过卫星的数据路径就会丢失,从而导致收入减少。

卫星通常使用各种方法来实现可用性,从辐射加固其组件到整合冗余系统与总线。但容错机制在这个平台中甚至更加深入,位于处理器本身之中。主处理器是一个 16 位的航空电子类处理器,它包含两个执行锁步 (lock-step) 中指令的内部 CPU。系统会对这两个内部 CPU 的输出进行比较,如果发现差异(通常由导致意外事件的 alpha 粒子引起),则暂时会处理器暂时是不可靠的,而且冗余处理器中会出现热交换。冗余处理器(或 热备件)通过一块简单的共享内存(在主与从之间共享)在总体运行上保持最新,以便能够即时控制卫星,从而确保不会丢失指向。

这些概念在 20 世纪 80 年代肯定算不上新鲜,它们一直应用至今,为系统设计各个方面的 HA 提供支持。围绕冗余性打造的设计目标是(在一定程度上)消除单点故障。除针对软件 HA 的开源产品之外,本文还探讨了应用于虚拟化环境的冗余与故障恢复的一些概念。

云 HA

这里讨论的方法是能够与商业软件共用。这仍然意味着故障级别与商业软件一致,但这些方法的确对其有所改进。真正的企业级容错(比如 IBM 大型机中的容错)是一门同时涵盖硬件与软件的复杂而又精细的科学。本文仅探讨如何以纯软件方式实现这些技术。

 

带故障恢复的 HA

冗余是一种提高系统可用性的常用方法。这种方法适用于所有级别的系统,从网络连接冗余(目的是管理停机与联网错误)到电力供应冗余(目的是最小化电力丢失的影响),再到存储冗余(通过镜像之类的复制或者对独立磁盘 [RAID]-5 的冗余阵列使用错误代码,比如 Exclusive OR [XOR])。

这种方法也可以用于更高级别,即所有服务器都是冗余的,以便最大限度地减少停机时间。借助冗余服务器,从故障服务器切换到备用服务器的过程称为故障恢复(或热交换)。出现故障时使用的服务器称为备用 服务器,如果服务器是活动的,则称为热备用 服务器,如果服务器是关闭的,在执行故障恢复过程之前需要启动它并对其进行初始化,因此也将该服务器称为 冷备用 服务器。尽管热备用可以让故障恢复所需的时间降至最低,但它仍然需要消耗电力,因此性价比不高。

让我们看一看这两种故障恢复方法(有状态的与无状态的)以及它们支持的各种模型。

无状态的故障恢复

无状态的故障恢复是最简单的方法,但也是作用最有限的方法,因为该方法在故障服务器与备用服务器之间没有维护任何状态。

在最简单的情况下,每台服务器配备一台备用服务器,用于故障恢复。使用相同的方法识别活动服务器(或其应用程序)何时出现故障(比如通过一次心跳),之后备用服务器就会接管控制权。如果是 Web 服务器,负载平衡器将移除故障服务器,并使用备份服务器替代它作为 Web 请求的目标。此过程如 图 1 中所示。


图 1. 简单的无状态故障恢复示例 
简单的无状态故障恢复示例 

这类解决方案可通过 Linux-HA 项目实现。Linux-HA 是一个基于 HA 群集系统开发的一组 HA 开源构造块的项目。它包括一个消息收发层,一组资源代理(它为群集资源提供标准化的接口),一个心跳守护程序(允许新的或故障资源进行注册和发出通知),以及一个群集资源管理器(用于提供服务编排)。

这里的资源 是指实体,比如 Apache Web 服务器的实例,或者设备上挂载的文件系统的实例。资源代理通常的实现形式是公开一组资源操作(比如启动、停止与监控)的 shell 脚本。 这些操作给资源管理器提供一个标准化接口。Linux-HA 项目提供一个包含大量资源代理的库(参见参考资料 以了解有关的详细信息)。图 2 显示了这个软件堆栈的视图。


图 2. HA 群集软件堆栈
显示了 HA 群集软件堆栈的图片 

参考资料 部分还提供一个可用于各个群集堆栈层次(比如消息收发、管理、资源)的开源程序包的列表。您还可以找到指向其他有用开源程序包的链接,比如策略引擎与其他资源管理守护程序。

有状态的故障恢复

尽管无状态的故障恢复可以在大量使用模型中发挥作用,但它有状态的情况下无疑表现并不理想。例如,如果某个操作系统或应用程序要维护与故障恢复服务器相关的信息(比如应用程序状态,操作系统级信息如网络连接),则需要使用更加复杂的方法。这种方法将提供一种透明且及时的迁移,而操作系统或应用程序并不知道此迁移过程的发生。

Xen 管理程序中实现了一种迁移方法,该方法借鉴了 Remus 研究项目的工作成果,而在基于内核的虚拟机 (KVM) 中通过 Kemari 项目提供的功能实现迁移。Remus 或 Kemari 项目定义了一个有状态的 VM 迁移方法,可将 VM 从故障服务器透明地迁移到新服务器,而且整个过程是连续的。两种方法(Xen 与 KVM)都依赖于现有的动态迁移功能,因此我首先会介绍动态迁移功能,然后探讨有状态的 VM 故障恢复。

动态迁移

动态(或在线)迁移是大多数管理程序中已实现的一项功能,该功能允许在不停机的情况下将 VM 从一台物理服务器移动到另一台物理服务器上。从 VM 的角度看,迁移是透明的,唯一可见的副作用是给外部通信带来了少量延迟。注意,动态迁移这项功能并非仅限于平台虚拟化(通过管理程序)使用。您还可以通过像 OpenVZ 这样的开源产品,在操作系统虚拟化的环境中实现动态迁移。操作系统虚拟化利用了现有的挂起与恢复功能。

迁移过程的中心是打包 VM 的挂起状态(存储在内存中),并将这些包移动到新主机上,然后恢复 VM 来执行相关操作。挂起 VM 并将它迁移到新主机的过程通常称为 停止与复制,因为是暂停 VM 之后才进行迁移(但也可以预先进行复制)。如果从旧主机迁移到新主机的页面数量众多(脏工作集),则会导致十分明显的延迟。

连续的动态迁移

Remus 项目(来自英属哥伦比亚大学)采用了动态迁移的理念,并将其改造为在 VM 环境中提供 HA。这是通过不断前移到另一台服务器的过程来实现的。备用或影子服务器是活动服务器的一个连续检查点,它通过对传统动态迁移过程进行两处主要改动来实现。

第一处改动与主机之间内存页面的迁移有关。前面曾经讲过在迁移页面时继续运行 VM 的动态迁移,该迁移也称为预先复制;当到达脏页面的阙值时,动态迁移会进入停止和复制阶段,这时 VM 会暂时挂起,以便移动所有脏页面。在连续的动态迁移中,活动主机(在停止与复制阶段中)不断使用检查点执行预先复制。其实,活动的管理程序(借助停止与复制)将执行动态迁移,但会让 VM 一直运行在当前的活动主机上。停止与复制阶段的结果本身就是一个检查点。当出现故障时,备份管理程序(位于独立的物理服务器上)使用最近的检查点来重新启动映像(参见 图 3)。


图 3. 通过不断动态迁移实现的 VM HA 
图片显示了通过不断动态迁移实现的 VM HA 

第二处改变与活动 VM 中的 I/O 相关。尽管内存的管理很繁琐,I/O 同步是一个更为复杂的问题。直到出现检查点时,才会保存网络包。一旦备用主机表明检查点已完成,则会释放这些网络报,并允许保存主机的外部状态以实现联网。存储方面的问题更加复杂,但可通过在备用主机中的简单映像进行解决。当将一个数据块写入活动磁盘时,该数据块也将写入备用主机。在出现检查点时,就会释放磁盘缓存。

检查点频率是可配置的,但文档记录是每 25 毫秒出现一次。让检查点以如此之高的频率出现,不但可以让必须传输的脏页面的数量降至最低,而且还最大限度地降低网络与存储帧的缓存成本。

您如今可以在开源管理程序中找到连续动态迁移的解决方法。Xen 是来自项目 Remus 的这些理念的首个目标,但 KVM 也通过存储帧 (storage frames) 项目实现了这项功能。这两种方法均运行在未经修改的操作系统之上。您可以在 参考资源部分中了解有关的详细信息。

 

其他方法

尽管这里讨论的方法已经顺利转变为领先的开源管理程序,但在该领域中,仍有大量的工作要做。

1995 年,Thomas Bressoud 与 Fred Schneider 通过复制协议仔细研究管理程序环境中容错机制的实现。在 Remus 之前,有一个叫做 SecondSite 的项目为 Remus 提供了基础与核心概念。SecondSite 还发现,压缩脏页面能够将单次 VM 复制的带宽提高 80%。

但最有趣的方法之一是一个叫做 ExtraVirt 的项目,它的研究重点是通过虚拟化管理瞬时处理器错误。ExtraVirt 定义了一个基于多核心处理器的管理程序,在每个单独的核心上运行 VM 的副本。VM 级别的复制由管理程序进行管理,并监控它们的输出(在它们可见之前),以便检测它们,然后从内部处理器错误进行恢复。VM 通过 VM 日志记录与回放保持一致。ExtraVirt 是作为 Xen 管理程序的扩展来实现的。

ExtraVirt 是一个基于虚拟化的容错解决方案,但其他类似的模式也可用于解决处理器级别的容错。一些有趣的方法包括 Software Implemented Fault Tolerance (SWIFT) 与 Error Detection by Duplicated Instructions (EDDI)。EDDI 复制指令流的作用是检查最后得到的数据流结果。如果结果一致,则不会出现错误;否则如果结果不一致,就会找出错误并进行相应的处理。编译器负责生成,然后汇集复制的指令流,从而形成一个只支持软件的解决方案。SWIFT 项目采用了类似的方法,但实现模式更加有效,它会收回已复制指令未使用的指令级别的资源。

 

结束语

Xen 与 KVM 在不断发展,通过新的功能来满足具有容错需求的新市场。这类功能十分适用于云环境,因为它为商业服务器上的企业级功能提供了另一个 解决方式(或服务水平协议)。尽管动态迁移是在服务器群集上实现负载平衡的一项重要功能,基于动态迁移构建的故障恢复在针对依赖 HA 的应用程序的云中打开新的应用程序。

 

参考资料

学习

  • Distributed Replicated Block Device 的高可用性(M. Tim Jones, developerworks, 2010 年 8 月)讲述了一种数据镜像方法。DRBD 是一个开源项目,它提供在两台服务器与两台存储设备之间分摊的 RAID-1-type 功能。 
     
  • Linux-HA 项目 是一个项目集,它自从 1999 年以来已为 Linux® 和其他平台实现了 HA。Linux-HA 项目是一个录属项目,包括大量用于构建 HA 群集系统的 HA 构造块。 
     
  • 群集系统的消息收发层提供了解服务存在(或缺少)所必需的消息收发与成员功能。消息收发层的例子包括 HeartbeatCorosync 和 OpenAIS。还有一个叫做 Cluster Glue 的软件包,它实质上是一套多种多样的组件,包括错误报告、库与实用工具。 
     
  • 资源代理 充当着群集生态系统中实体的标准化接口。这些代理可以是软件服务如 Apache Web 服务器 或物理服务如音响警报器。 该链接提供一个针对各种服务的最新资源代理列表。 
     
  • Pacemaker 是一个群集资源管理器,用于编排群集的管理行为(启动与停止服务,监控等)。Pacemaker 是 Linux-HA 解决方案的关键组成部分之一,您可以了解关于它的 架构 的更多信息,包括对其他组件如 pengine 策略引擎以及各种资源代理的介绍。您还可以了解关于 pacemaker CLI、其设计目标以及命令列表的更多信息。 
     
  • 通过持续 VM 同步来实现 HA 故障恢复已经在 Xen 与 KVM 中得以实现。 您可以在它们的项目网(Remus 与 Kemari)上了解关于这些实现的更多信息。 
     
  • 在 Hypervisor-based Fault ToleranceSecondSite (Remus 的前身)、ExtraVirt (可通过虚拟化管理瞬时处理器错误),以及 SWIFT (可通过复制的指令流实现特定于软件的容错)中可以找到围绕容错的其他工作成果。 
     
  • 在 developerWorks 云开发人员资源 中,发现和共享应用程序和服务开发人员有关 构建云部署项目的知识和经验。 
     
  • 浏览 技术书店 中关于这些与其他技术主题的书籍。