群集和应用程序部署
以前我们曾经介绍过主动/主动或主动/被动群集和应用程序,由于早期的产品仅支持 2 节点群集,因此这种形式的部署是它的自然结果。但是在一些情况下,这可能会导致混淆,因为这些术语可以用不同的方式来解释,具体取决于上下文是 1) 给定的应用程序实例如何运行 2) 不同的应用程序实例如何运行,或是 3) 群集中的节点是否正在执行有用的工作。为了完全了解特定应用程序和群集的部署,我们需要了解以下信息:
• | 有多少个应用程序实例正在运行? |
• | 在群集中有多少个相同数据的实例? |
• | 数据实例是否会移动? |
• | 相同应用程序的不同实例是否运行在不同的群集节点中? |
• | 不同的应用程序可以运行在不同的群集节点上吗? |
• | 应用程序给服务器带来了何种类型的负载,以及如何在故障转移之后重新分配这些负载? |
在介绍如何部署应用程序之前,我们必须首先定义什么是应用程序。在本文中,应用程序被定义为向终端用户或客户端提供一种服务的运行中的代码和数据。可以用一对不同的示例来解释这一点:工作站上运行的一个 Microsoft Word 实例是一个应用程序实例。如果有多个 Word 实例正在运行,则每个实例会被视为一个不同的应用程序实例。然而,还有更为复杂的应用程序。例如,对于 Microsoft SQL Server 来说,一个数据库被视为一个应用程序实例。而多个独立的数据库则被视为不同的应用程序实例。但是,一个数据库可以分区成多个 SQL Server 实例并使用 SQL Server 查询引擎联系在一起。这种情况下,联系在一起从而提供一个数据库镜像的这组 SQL Server 应用程序实例就可以视为一个应用程序实例。
基本上,将以下五种属性放在一起就可以全面了解部署的目的,并可以解释部署的原因或是表现部署的特点:
• | 服务器负载 多少服务器资源被它所支持的应用程序所消耗,以及故障转移会如何影响这种资源利用? |
• | 应用程序样式 应用程序是整个在一个节点上运行,还是被分割成多个较小程序块在群集中运行? |
• | 应用程序部署 在给定部署下应用程序块如何在群集中分配? |
• | 故障转移策略 在故障转移后应用程序会执行何种操作? |
• | 应用程序实施 应用程序本身如何被实施? |
服务器负载
在部署应用程序时,很重要的一点就是要考虑应用程序会对服务器资源产生什么要求。如果使用群集,则还有一些相关问题需要考虑:在故障转移后如何重新分配负载?
服务器负载 基础
让我们来看一个最简单的示例,一个主动/主动式 2 节点文件服务器群集,其中节点 A 和节点 B 各服务于一个共享。如果节点 A 出现故障,它的资源就会移给节点 B,从而增加了节点 B 的负载。实际上,如果节点 A 和 B 在出现故障前都仅运行各自容量的 50%,那么在故障转移完成后,节点 B 将会完全饱和(100% 的容量),这从性能上来说是可以承受的。
尽管不是最好的情况,但是您要记住的很重要的一点是,如果所有应用程序仍在运行,即使性能有所下降,相对于没有群集提供的高可用性保护的情况来说,这都是一个 100% 的进步。但是这带来了风险的概念,以及为了保护应用程序的性能和可用性,您可以接受多少数量的应用程序的问题。
为了清楚地说明这个问题,我们有意选择了最坏的情况(一个主动/主动 2 节点群集,每个节点运行一个应用程序,每个应用程序消耗一半的服务器资源)。如果再加上一个节点,这种平衡就会改变:有更多的服务器用来支持负载,但如果三个节点都运行在 50% 的容量,而有两个节点出现故障,则剩下的服务器将无法处理那两个故障节点累积的应用程序负载。当然,两个故障的可能性相对来说小于一个故障,因此风险相对来说也比较小。
尽管如此,在群集中部署应用程序时仍必须考虑负载/风险平衡。群集中节点越多,就有越多种分配工作负载的选择。如果您要求所有群集应用程序在运行时不能有任何性能下降,那么您可能需要考虑使用某种形式的主动/被动配置。但即使是在这种情况下,您也必须考虑不同配置的风险。如果您在任何情况下都无法接受哪怕是最轻微的性能下降,那么您将需要为每个主动节点配备一个专用的被动节点。
另一方面,如果您认为多个故障同时出现的风险较小,您也可以有另外的选择。如果您具有 4 个节点或 8 个节点的群集,您可能会考虑 N+I 配置。在 1.4.3 节会详细介绍 N+I,它是主动/被动形式的一种变体,其中 N 个节点是主动节点,I 个节点是被动节点或保留节点。通常,I 的值小于 N,这样 N+I 群集拓扑就可以处理 I 个故障而不会出现任何性能下降。风险就在于,如果出现多于 I 个故障,那么性能就有可能下降,不过再说一次,同时出现多个故障的可能性是很小的。
因此,N+I 群集是一个非常有用的配置,它在 100% 的被动服务器容量与较低水平的多个群集节点故障风险之间均衡了硬件成本。
服务器负载 更现实的一些配置
上述示例比较简单,它假定应用程序将整个负载都加在一台服务器身上,因此在故障转移的情况下,它的资源利用不能分布到其余的多台服务器中。实际情况通常不是这样(尤其是文件和打印服务器),因此,让我们再来看看其他 4 节点群集(就称为 ABCD 吧)的示例,这个群集具有节点 A、B、C 和 D。
通常情况下,一台服务器将会支持多个应用程序的负载。如果正常情况下每台服务器的负载率为 25%,那么 ABCD 群集就可以在其中三个成员出现故障的情况下存活,而不会丧失应用程序的可用性(这几乎是最坏的情况)。
以下数字序列说明了 4 节点群集在出现连续节点故障情况下的应用程序负载。阴影区域表示运行中的应用程序的容量要求。更进一步,以下示例假定应用程序在任何给定服务器上的负载都是可分的,可以重新分配到任何存活的节点上。
图 1.1:正常条件下运行的群集(每个节点的负载率为 25%)
图 1.2:一个节点故障后的群集。请注意应用程序负载的重新分配。
图 1.3:两个节点故障后的群集。现在每个存活节点的负载率大约为 50%。
图 1.4:在三个节点故障后,剩下的一个存活节点已运行在满容量。
如果每个节点以 75% 的容量运行,那么在没有合理的故障转移策略的情况下,即使是一个节点故障也可能导致应用程序可用性丢失。然而,您可以根据应用程序来指定在出现服务器故障的情况下,一部分应用程序应当故障转移到节点 A、B、C 和 D。如果应用程序均匀分布到存活节点上,那么现在这个群集在失去一个节点的情况下仍可存活,因为出现故障的服务器负载已被平均分配给三个存活的节点(75% 的三分之一是 25%)。最后的结果就是三个完全负载的服务器(本来每个节点运行 75% 的容量,现在又加上 25%),但所有应用程序仍然可用。
作为上述示例的变体,以下数字序列将介绍一个 4 节点群集,每个节点大约运行 33% 的容量。更进一步,在这个示例中,应用程序负载是不可分的,在故障转移的情况下也不能分布到多个其他服务器中(这可能是一个应用程序或是多个依赖于相同资源的应用程序)。
图 2.1:正常条件下运行的群集(每个节点的负载率为 33%)
图 2.2:一个节点故障后的群集。 请注意重新分配后的应用程序负载。
图 2.3:第二个节点故障后的群集。每个存活的节点现在大约运行在 66% 的容量。请注意,如果再有一个节点出现故障,这个群集将不能支持全部四个应用程序。
图 2.4:在出现第三个故障后,唯一存活的服务器只能支持四个应用程序中的三个。
另外一种故障转移策略是“故障转移对”(Failover Pairs),也称为“伙伴对”(Buddy Pairs)。假定四台服务器中每台服务器的负载率为 50% 或更少,那么一个故障转移伙伴就可以与每台服务器关联。这种配置使得群集在出现两个故障的情况下仍可存活。有关“故障转移对”的更详细信息将在 1.4.1 节介绍。
利用前面的“故障转移对”示例,我们可以通过使两台服务器的负载达到 100% 容量并配备两台被动备份服务器,将它转为一个主动/被动配置。这种主动/被动配置在两个故障的情况下也可以存活,但是在正常情况下,有两台服务器没有利用。而且,这些 100% 负载的服务器的性能也比不上“故障转移对”配置,后者每台服务器仅运行在 50% 负载。在这两个示例中,请注意您具有相同数量的服务器、相同数量的应用程序以及相同数量的存活率(即可以有多少个节点出现故障而不会危及应用程序可用性)。但是,无论是从性能上还是从经济性来说,“故障转移对”都明显优于主动/被动模式。
仍旧使用 ABCD 4 节点群集,让我们来看看如果我们将它配置为 N+I 群集(会在 1.4.3 节中详细介绍)——其中三个节点运行在 100% 容量,一个节点作为备用节点——又会怎样。这个群集只能在一个故障的情况下存活。但是与前面一样,跟每台服务器运行在 75% 容量的情况相比,您仍然拥有相同数量的服务器、应用程序以及相同的存活率,但在您让被动节点备份运行在 100% 负载的主动节点时,从性能上和经济性上仍然可以承受。
应用程序样式
现在是考虑应用程序设计的一些方面,以及它如何影响应用程序部署的时候了。群集中运行的应用程序可以归纳为:
• | 单实例 在单实例应用程序中,在任何时间点上群集中只有一个应用程序实例在运行。这种情况的一个示例就是服务器群集中的 DHCP 服务。在任何时间点上,群集中只有一个 DHCP 服务在运行。利用服务器群集提供的故障转移支持,这个服务具有高度的可用性。单实例应用程序通常具有不能分区到其他节点的状态。在 DHCP 的情况中,已租用的 IP 地址范围相对较小,但在较大的环境中时可能具有较高的不稳定性。为了避免在群集中同步状态的复杂性,这个服务会作为单实例应用程序运行。 图 3:单实例应用程序 在上述示例中,群集具有四个节点。根据定义,单实例应用程序一次只能运行在一个节点上。 | ||||
• | 多实例 多实例应用程序由相同代码的多个实例或代码的多个不同代码块组成,可以在群集中执行这些实例或代码块,并通过集成各自的结果来提供一个服务。这些实例的集成向终端用户或客户端计算机提供了一个服务的假象。根据应用程序和数据的类型,有两种不同类型的多实例应用程序:
|
应用程序部署
根据部署何种类型的应用程序以及部署在相同群集上的应用程序数量,可以采用多种不同的方式在群集中部署应用程序。这些方式可以归纳如下:
1. | 一,单实例应用程序 在这种类型的部署中,一个群集节点用于执行应用程序和服务于客户请求,而其他节点则作为备用节点,等待着在出现故障的情况下承载应用程序。这种类型的部署通常适合于 2 节点故障转移的群集,而不能用于 N 节点群集,因为 N 节点群集只使用 1/N 的总体容量。这也就是一些人所说的主动/被动群集。 |
2. | 一些,单实例应用程序 多个单实例应用程序可以部署在相同群集上。每个应用程序都独立于其他应用程序。在故障转移群集中,每个应用程序都可以独立于其他应用程序进行故障转移,因此如果承载多个应用程序的节点出现故障,这些不同的应用程序可能就要故障转移到群集中的其他节点。这种类型的部署通常用于合并的情况,在这种情况下,多个应用程序分布在一组节点上,并且群集提供了一个高度可用的环境。在这种环境中,需要谨慎地进行容量规划,以便确保在出现故障的情况下,各节点仍具有足够的容量(CPU、内存 IO 带宽等)用以支持增加的负载。 |
3. | 单一,多实例应用程序 在这种环境中,尽管群集仅支持一个应用程序,但应用程序的多个程序块却运行在多个不同的节点上。在克隆应用程序的情况下,每个节点都针对相同的数据运行相同的代码。这是典型的 web 前端情形(群集中的所有节点都是一样的)。在出现故障的情况下,容量会减少。在分区应用程序中,各分区通常部署在群集的多个节点上。发生故障时,可以在一个节点上承载多个分区。需要进行谨慎的规划,以便确保在出现故障的情况下,可以达到应用程序 SLA。以 4 节点群集为例。如果某个应用程序被分为四个程序块,那么在正常运行时,每个节点将承载一个分区。如果有一个节点出现故障,那么有两个节点将继续承载一个分区,而另一个节点则要承载两个分区,从而可能给第 3 个节点造成两倍的负载。如果应用程序被划分成 12 个分区,那么在正常情况下每个节点将承载三个分区。在出现故障的时候,每个分区都可以配置为故障转移到不同的节点,因此剩下来的节点就可以每个节点承载四个分区,从而使得负载均匀分布。但代价就是,支持 12 个分区的开销要比支持 4 个分区来得高。 |
4. | 一些,多实例应用程序 当然,多个多实例应用程序可以部署在相同的群集上(实际上,单实例和多实例可以部署在相同群集上)。在多个克隆应用程序的情况下,每个节点都只运行每个应用程序的一个实例。在分区应用程序的情况下,容量规划以及定义故障转移目标变得更为复杂。 |
故障转移策略
通常,故障转移是单实例应用程序和分区应用程序的多个分区所使用的机制,用来提供高可用性(术语“数据包” (Pack) 用于描述具有高可用性的单实例应用程序或分区)。
在 2 节点群集中,定义故障转移策略没有什么价值。如果一个节点出现故障,唯一的选择就是故障转移到另外一个节点。随着群集大小的增加,使用不同的故障转移策略随之成为可能,并且每个策略都具有不同的特点。
故障转移对
在大型的群集中,可以对故障转移策略进行定义,使得每个应用程序都可以在两个节点之间实现故障转移。以下这个简单的示例显示了一个 4 节点群集中的应用程序 App1 和 App2。
图 8:故障转移对
这种配置具有以下优缺点:
非常适合于支持大量2 应用程序的群集,例如数据库。这种配置保证了在出现故障的情况下,两个应用程序不会分布在相同的节点上。 | |
规划容量是非常容易的。每个节点都可以根据它将要承载的应用程序来设定其容量大小(就像承载一个应用程序的 2 节点群集一样)。 | |
节点故障对系统可用性和性能的影响很容易确定。 | |
具有大型群集的灵活性。在一个节点出现故障的情况下,给定应用程序的伙伴可以进行动态更改(最后可能采用下面的备用策略)。 | |
在一个较简单的配置中(例如上述配置),只有 50% 的群集容量处于使用中。 | |
在出现多个故障的情况下可能需要管理员干预。 |
使用所有版本的 Windows 的服务器群集通过将每个资源的可能的所有者列表限定给指定节点对,从而支持故障转移对。
热备用服务器
为了降低故障转移对的开销,可以将每个故障转移对中空闲的节点合并为一个节点,从而形成一个可以在出现故障的情况下承担工作的热备用服务器。
图 9:备用服务器
备用服务器配置具有以下优缺点:
非常适合于支持大量应用程序的群集,例如数据库。 这种配置保证了在出现故障的情况下,两个应用程序不会分布在相同的节点上。 | |
规划容量是非常容易的。每个节点都可以根据它将要承载的应用程序来设定其容量大小,空闲节点的大小可以设定为其他节点的最大值。 | |
节点故障对系统可用性和性能的影响很容易确定。 | |
配置的目标是为了应付单点故障。 | |
并不能真的很好地处理多个故障。在计划的维护期间空闲节点可能处于使用中,这时候可能会出现问题。 |
目前,服务器群集可以通过结合使用可能的所有者列表和优先的所有者列表,从而支持备用服务器。优先节点应设为应用程序默认会在其上运行的节点,而给定资源的可能的所有者则应设为优先节点和空闲节点。
N+I
备用服务器在一些配置情况下可以很好地用于 4 节点群集,但是它处理多个故障的能力比较有限。N+I 配置是备用服务器概念的延伸,其中 N 个节点承载应用程序,I 个节点空闲。
图 10:N+I 空闲节点配置
N+I 配置具有以下优缺点:
非常适合于支持大量应用程序的群集,例如数据库或 Exchange。这种配置确保了在发生故障时,应用程序实例将会故障转移到空闲节点,而不是正在使用的节点。 | |
规划容量是非常容易的。每个节点的容量大小是根据其将要承载的应用程序来设定的。 | |
节点故障对系统可用性和性能的影响很容易确定。 | |
配置在出现多个故障时也能很好工作。 | |
并不能真的很好地处理运行在相同群集中的多个应用程序。这种策略最适合于运行在转移群集的应用程序。 |
在 Windows Server 2003 版本下,服务器群集可利用群集组公用属性 AntiAffinityClassNames,从而支持 N+I 方案。这个属性可以包含由多个字符组成的任意字符串。在发生故障转移时,如果被故障转移的某个组的 AntiAffinityClassNames 属性中含有非空字符串,那么故障转移管理器就会检查所有其他节点。如果在资源的可能的所有者列表中有哪些节点没有承载与 AntiAffinityClassNames 具有相同值的组,那么这些节点就会被认为是最佳的故障转移目标。如果群集中的所有组都承载了含有与 AntiAffinityClassNames 属性相同值的组,那么就会使用优先节点列表来选择故障转移目标。
故障转移环
故障转移环允许群集中的每个节点运行一个应用程序实例。在出现故障时,故障节点上的应用程序会移到序列中的下一个节点。
图 11:故障转移环
这种配置具有以下优缺点:
对于支持多个小应用程序实例的群集很理想,在这样的群集中,任何节点的容量都足够大,能够同时支持多个实例。 | |
节点故障对于性能的影响很容易预测。 | |
规划单一故障的容量较为容易。 | |
这种配置对于所有类型的多个故障的效果都不是很好。如果节点 1 出现故障,节点 2 将承载两个应用程序实例,而节点 3 和节点 4 将承载一个应用程序实例。如果节点 2 接着出现故障,节点 3 就要承载三个应用程序实例,而 4 仍然只承载一个应用程序实例。 | |
不太适合于大量应用程序,因为可能存在多个实例最终由同一节点来承载的情况,即使存在负载较轻的节点。 |
在 Windows Server 2003 版本下,服务器群集支持故障转移环。这是通过使用优先的所有者列表来定义给定组的故障转移顺序而实现的。应当先选择节点顺序,然后对优先的节点列表进行设置,使得每个组都从不同的节点启动。
随机
在大型群集——甚至是运行多个应用程序的 4 节点群集中,为每个应用程序定义具体的故障转移目标或策略会非常繁琐,同时也易于出错。在一些情况下,最好的办法就是让系统随机选择目标,这种办法可保证在统计可能性的前提下,出现故障时负载会分布到群集中。
随机故障转移策略具有以下优缺点:
对于支持多个小应用程序实例的群集很理想,在这样的群集中,任何节点的容量都足够大,能够同时支持多个实例。 | |
管理员不用决定应用程序的故障转移目标。 | |
只要有足够数量的应用程序或者说应用程序被分区地足够细致,这种办法就可以提供一个良好的机制,在出现故障时将应用程序分布到整个群集中,从而实现统计上的负载平衡。 | |
配置在出现多个故障时也能很好工作。 | |
很容易进行调整,可以很好地处理运行在相同群集中的多个应用程序或相同应用程序的多个实例。 | |
比较难以规划容量。实际上无法真正保证负载会在整个群集中平衡分布。 | |
节点故障对于性能的影响不容易预测。 | |
不太适合于大量应用程序,因为可能存在多个实例最终由同一节点来承载的情况,即使存在负载较轻的节点。 |
Windows Server 2003 版的服务器群集在出现故障时会随机安排故障转移目标。在承载资源组的节点出现故障的情况下,每个具有空的优先所有者列表的资源组都会被故障转移到群集中的随机节点
自定义控制
在一些情况下,某个给定的应用程序实例可能会优先选择特定节点。
将应用程序与节点关联起来的配置具有以下优缺点:
在出现故障时,管理员对于将要发生什么事情具有完全控制能力。 | |
因为故障方案可以预测,因此比较容易规划容量。 | |
由于群集中有很多应用程序在运行,因此定义一个良好的故障策略会非常复杂。 | |
难以规划多个、层叠式的故障。 |
服务器群集可以利用优先的节点列表功能,完全控制故障转移的顺序。优先的节点列表的全部语义可以定义如下:
优先的节点列表 | 通过管理员将组移到最可能的节点 | 因为节点或组故障而进行故障转移 |
在群集中包含所有节点 | 组被移到群集中仍在运行的优先的节点列表中的最高节点。 | 组被移到优先的节点列表中的下一个节点。 |
在群集中包含节点的子集 | 组被移到群集中仍在运行的优先的节点列表中的最高节点。 如果优先的节点列表中不存在仍在运行的节点,那么就将组移到随机节点。 | 组被移到优先的节点列表中的下一个节点。 如果承载组的节点是列表中的最后一个节点或不在优先的节点列表中,那么就将组移到随机节点。 |
空 | 组被移到随机节点。 | 组被移到随机节点。 |
负载平衡
负载平衡是一个术语,它具有多个不同的意义。在群集环境中,通常以两种不同的方式使用负载平衡:
• | 在一组克隆中分布客户端请求 在 Windows 中,“网络负载平衡”(NLB) 可以将客户端 TCP/IP 请求分布到一组节点中(通常是 Web 服务器或 ISA 阵列或终端服务器计算机)。也可以通过外部网络基础结构(例如 CISCO 本地定位器)来实现这一功能。 | ||||
• | 在故障转移群集中优化计算资源 支持故障转移的群集允许应用程序实例在群集中移动。在以前,这种方法用于确保出现故障时,应用程序可以在其他地方重新启动。但是,现在这种机制可以与性能计数器和应用程序负载方法结合使用,从而提供一种在群集节点中平衡应用程序负载的方法。这可以通过以下两种方式之一实现:
|
1 这是一个笔误,应用程序具有状态,但是这个状态不会跨越多个客户端请求。
2 大量应用程序也是消耗大量系统资源(例如 CPU、内存或 IO 带宽)的一个原因。