当前位置 博文首页 > weixin_34304013的博客:在Windows Server 2012中搭建SQL Server

    weixin_34304013的博客:在Windows Server 2012中搭建SQL Server

    作者:[db:作者] 时间:2021-08-12 17:59

    OK~ WSFC 2012 R2 年度盛宴开始~ 在本文中,老王将用一系列的场景,把动态仲裁,动态见证,票数调整,LowerQuorumPriorityNodeID,阻止仲裁等群集仲裁技术串起来,完成一个又一个复杂的场景,本篇文章可能并不太适合对于WSFC不了解的朋友,适合对于WSFC群集仲裁技术及2012动态仲裁技术有一定初步了解的朋友,如果您还不了解WSFC,建议您去先看下老王写过的博客,或者其它地方相关的资料,如果您对于WSFC仲裁,动态仲裁技术已经有了初步的了解,相信跟这老王这篇文章中的场景会帮助您更加深入的理解群集投票,动态仲裁等知识,话不多说,我们现在就开始,跟这老王上车吧,过山车开了~滴

    ?

    ?开始之前先介绍环境,为了准备这次的博客,老王一共开了七台虚拟机,主要是为了重现一些真实的分区场景,之前在2008R2的时候,我们用了六台服务器,两边各两个节点,一台域控,一台ISCSI,但是只有一侧有域控,另外一侧没有域控,因此发生分区时,没有域控的一方是没办法上线联机抢夺群集的,虽然效果是一样的,最终两端出现分区,群集都无法使用,我们强制选择其中一方启动,在这次的环境里面老王特地用了七台服务器,两端都有域控,都可以形成群集的一个场景

    ?

    ? 环境介绍

    ?

    ? 北京站点

    ?

    ? ?HV01

    ? ?MGMET:80.0.0.2 ?GW:80.0.0.254 DNS:80.0.0.1 100.0.0.20?

    ? ?ISCSI:90.0.0.2

    ? ?CLUS:70.0.0.2

    ?

    ? ?HV02

    ? ?MGMET:80.0.0.3 ?GW:80.0.0.254 DNS:80.0.0.1 100.0.0.20

    ? ?ISCSI:90.0.0.3

    ? ?CLUS:70.0.0.3

    ?

    ? ?BJDC&ISCSI

    ? ?Lan:80.0.0.1 GW:80.0.0.254

    ? ?ISCSI:90.0.0.1

    ?

    ? 佛山站点

    ?

    ? ?HV03

    ? ?MGMET:100.0.0.4 ?GW:100.0.0.254 DNS:100.0.0.20?80.0.0.1

    ? ?ISCSI:90.0.0.4

    ? ?CLUS:70.0.0.4

    ?

    ? ?HV04

    ? ?MGMET:100.0.0.5 ?GW:100.0.0.254 DNS:100.0.0.20 80.0.0.1

    ? ?ISCSI:90.0.0.5

    ? ?CLUS:70.0.0.5

    ?

    ? ?FSDC

    ? ?Lan:100.0.0.20 GW:100.0.0.254

    ?

    ?Router?

    ? ?

    ? ? 03Route

    ? ? Beijing:80.0.0.254

    ? ? Fuosha:100.0.0.254

    ?

    ? ?首先我们先来看一道开胃小菜,在这个场景中我们将模拟,一个四个节点的跨站点群集,在见证磁盘始终在线的情况下节点逐个宕机的场景,以下是老王已经组建起来的一个多站点群集,其中的群集名称和群集IP,可能在后面的图会变,因为实验过程中老王拆了又建了几次群集,不过其他架构都按照规划好的不会改变。

    技术分享

    技术分享

    技术分享

    可以看到我们在群集中跑了一个DTC应用,当前DTC应用绑定了两个IP地址,它们之间是OR关系

    技术分享

    ??

    ? ?在多站点群集的设计规划中有很多需要考虑的地方,例如存储复制,网络检测,加密处理,AD的同步,DNS的缓存等都会影响到多站点的故障转移时间,后续会单独写博客来详细讲,这里简单讲两个影响客户端直接访问的地方

    ?

    ? ?默认情况下在多站点群集中,例如我们的DTC应用当前在北京站点运行,它的联机地址会是80.0.0.89,当它转移到佛山站点,联机地址会是100.0.0.89,但是这时候,客户端能不能访问DTC服务呢,不一定

    ?

    ? ? 设想一下,北京和佛山站点做了AD多站点,它们的DNS会相互同步,当DTC在北京站点时它是80.0.0.89,经过一段时间它同步到了佛山站点,佛山的DNS也知道了DTC是80.0.0.89这个地址,那么当北京站点宕机,转移到佛山站点了,虽然这时候DTC应用已经联机,但是当客户端访问DTC,会返回80.0.0.89这个地址,并不会返回100.0.0.89的可用地址,这也导致了停机时间的延迟

    ?

    ? ? 原因是由DNS的缓存机制导致,默认情况下群集应用联机后注册的主机记录都是会有1200秒的TTL,即是说,客户端如果请求了这个VCO的主机记录,1200秒以内,不会再重新请求了,会使用缓存中的地址

    ?

    ? ? 2008时代WSFC新增了用于多站点的HostRecordTTL属性,使我们可以设置VCO记录注册到DNS时的TTL,TTL生命周期现在可以进行缩短,微软建议缩短为300秒,即五分钟之后重新要求DNS更新新的地址

    ?

    ? ? 打开佛山站点的客户端,输入ipconfig /display可以看到被缓存的VCO记录和生存时间(TTL)

    ?

    ? ??技术分享

    ?

    ? ?另外一个2008时代新增用于多站点的属性则是RegisterAllProvidersIP,正常情况下,我们的VCO即使你设计了多个地址,它们默认会是OR的关系,即始终只注册一个群集IP地址,当前在北京站点就是80网段的地址,当联机到佛山站点,则会有CNO替VCO去注册更新成100网段的地址,同一时间VCO默认只有一个站点的地址在线,通过RegisterAllProvidersIP属性我们可以让CNO去帮我们注册所有的VCO地址,但是这就要求群集应用支持地址重试

    ?

    ? ?一个完美的场景应该是群集应用默认连接到80网段的地址,当80网段不可用,自动重试连接到100网段联机使用,因为所有地址都已经注册至DNS,所以可以减少由于DNS缓存导致的停机时间,在群集应用支持自动重试的话,可以使用这个属性 ,SQL Server 2012开始支持在连接字符串加入MultiSubnetFailover=True参数和RegisterAllProvidersIP配合使用,当连接其中一个地址不通,会自动连接另外一个

    ?

    这里我们遵循微软的建议,配置DTC应用的HostRecordTTL为300

    ?

    设置方法如下

    ?

    #获取群集应用资源名称?

    Get-ClusterResource | Select Name, ResourceType

    技术分享

    #获取群集应用资源属性

    Get-ClusterResource "devtestdtc" | Get-ClusterParameter

    技术分享

    #修改HostRecordTTL属性,脱机再联机可以看到设置已经生效

    Get-ClusterResource "devtestdtc" | Set-ClusterParameter HostRecordTTL 300

    技术分享

    辅菜说完,下面来看我们的正菜,可以看到目前我们是四个节点的群集,见证磁盘可以正常参与投票

    ?

    #查看节点投票数

    Get-ClusterNode | ft ID, NodeName, NodeWeight, DynamicWeight, State -AutoSize

    #查看见证投票数

    (Get-Cluster).WitnessDynamicWeight?

    ?

    这两个命令后面我们会经常用到

    技术分享

    当前群集DTC正常运行在HV01

    技术分享

    我们直接将HV01进行断电操作,可以看到群集应用自动转移至HV02,HV01已下线所以去掉了它的投票,同时由于现在是4票,所以自动去掉了见证磁盘的一票,始终保证投票数为奇数。

    技术分享

    直接将HV02也断电,我们彻底失去了北京站点,可以看到现在又自动加上了见证磁盘的一票,现在群集还是三票,我直接强制DNS服务器更新,然后在客户端ipconfig /flushdns了,此时再尝试联devtestdtc则会返回100网段的地址,如果不清除DNS缓存,可以等300秒时间到了,再次请求自动更新至100网段

    技术分享

    DTC当前在HV03上面运行,我们再把HV03也断电,现在群集只剩下HV04,可以看到现在群集会显示三票,但其实已经不重要了,因为我们只剩下一个节点,他可以和见证磁盘联系,因此可以存活至最后。

    技术分享

    以上是我们的第一道小菜,怎么样,还算简单开胃把,可以看出在见证磁盘在情况下,群集节点逐步宕机,WSFC2012R2会始终动态的调整群集投票,确保群集投票始终是奇数,即始终一方可以存活,最后可以只剩下一个节点和见证存活。

    ?

    接下来我们来模拟第二个场景,北京站点和佛山站点的管理网络失去联系,即80网络和100网络不通,我们直接关掉路由服务器,为了防止其中一方联系到见证磁盘获胜,我们也模拟见证磁盘失去联系

    ?

    技术分享

    这时候我们可以看到,群集检测到见证磁盘失效,已经自动调整三个节点投票数为奇数

    ?

    另外可以看到我们把管理网络断开了,群集依然可以正常工作,为什么呢,因为群集内置的网络拓扑生成器会实时自动生成调整全网检测的拓扑,管理网络既可以对外访问也可以做心跳检测,心跳网络只可以做心跳检测,因此只要不影响群集节点之间心跳检测,是不会有任何反应的。

    ?

    群集并不会知道你的管理网络故障,因为在北京站点管理网络可以正常访问,在佛山站点管理网络也可以正常访问,群集就以为它是好的,心跳检测还有其它卡可以进行嘛

    ?

    技术分享

    ? 假设现在这家公司的员工都从佛山出差来北京办公,即所有的用户都要在北京80网段的客户端访问,但是如果这时候群集DTC忽然漂移佛山去了,虽然它在佛山也可以正常工作,但是北京站点的用户都访问不到那边,因为我们知道佛山站点100网段已经和外界失去联系

    ?

    ? ?默认如果不做调整群集应用,DTC是应用是随机漂移的,不一定会漂到那个节点去,可能看那个节点内存多,它就过去哪里了,一旦漂到佛山站点的服务器就惨了

    ?

    ? ?这时我们可以通过以下手段进行控制,首先设置DTC的习惯节点为HV01,HV02,这样如果当前DTC托管在北京,当它发生故障转移的时候,会优先考虑转移到HV01或HV02

    技术分享

    ? ?但是仅仅设置首选所有者还是不够的,因为设置首选所有者,只是在没有发生分区的情况下会有用,当发生了一个网络分区,HV01 HV02没办法与HV03 HV04联系,这时由于HV01没有投票数,而HV03 HV04一方有投票数,所以应用还是会转移到佛山站点运行

    ?

    ? ?应对这种场景,我们可以彻底去掉HV03,HV04站点的投票数,这样做了之后,即便发生一个网络分区,北京站点剩下一票,佛山站点两票,但因为我们去掉了佛山站点两台服务器的投票数,所以佛山站点会尝试形成群集,但是始终是没办法成功的,因为他们没有合法的票数。

    ?

    ? ?即是说我们通过手动去掉投票数,让佛山的两个节点永远也没办法形成群集,要不然就访问北京的节点,北京的节点一旦无法启动,群集应用就停止访问或强制启动。

    ?

    #手动去掉群集投票数

    (Get-ClusterNode -Name hv03).NodeWeight = 0

    (Get-ClusterNode -Name hv04).NodeWeight = 0技术分享

    ?

    ? ?以上是手动调整群集投票数的场景之一,即我们知道一方的站点已经无法对外提供访问服务,需要让该站点始终停止对外服务,直到网络恢复再重新赋予投票数

    ?

    ? ?手动调整投票数老王认为是很有用处的一项技术,除了这种已知站点无法对外提供的场景,在其它很多场景下也都有用武之地

    ?

    ? ?例如在一个完全手动故障的场景,有北京,天津,河北三个站点,只有北京站点的节点有投票,手动取消了天津和河北的投票,因为当故障发生时,可能要举行一个灾难恢复会议,商讨一下,当前由那个站点继续承担群集更合适,例如商讨天津站点当前更合适承担群集,手动赋予天津站点节点票数,节点检测到当前有投票,于是天津站点形成群集,继续对外提供服务

    ?

    ? ?或者还有一个场景,假设当前有北京站点,河北站点两个站点,两个节点各有两个节点,当前群集一个四个节点,我手动去掉了河北站点其中一个节点的投票,让它失踪不参与群集投票,这时假设群集发生了故障,北京站点和河北站点的三个节点都已经无法启动提供服务,我们可以赋予之前去掉投票的节点,启动它,让它继续对外提供服务,或者北京站点宕机,所有业务都跑到河北站点的一个节点运行,已经把机器的负载跑满,这时候可以把去掉投票的节点重新赋予投票,加入群集,一起承担负载,这样作为一个灾备来使用。

    ?

    ? ? 接下来我们假设当前群集是动态仲裁,群集见证磁盘先失效,继而管理网络也失效,心跳网络也失效,出现一个分区时的场景

    ?

    ? ?针对网络分区,我们到时除了把路由服务器关了,也把HV03 HV04的心跳网卡直接改了个网络

    技术分享

    ? ? 针对见证磁盘失效,我们还是依旧采用直接ISCSI上面禁用磁盘的方式,可以看到大概过了30秒左右,仲裁检测到了见证磁盘已经处于非联机状态,于是自动去掉了它的票数,同时也随机去掉了一个节点的票数,现在群集变成了三票

    技术分享

    仲裁磁盘会按照故障转移策略,在各个节点尝试联机挂起

    技术分享

    都尝试失败后会显示为失败状态,过一段时间会在尝试联机挂起,但始终不会成功

    技术分享

    可以看到现在由于见证磁盘失败,仲裁已经动态的调整了投票数,又随机去掉了一个节点的投票数,现在群集还是奇数三个投票

    技术分享

    ?

    ? 如果这时一个网络分区发生,北京站点与佛山站点没办法心跳检测,没有网卡可以用于检测,这时候佛山的站点会获胜,继续对外提供服务,而北京站点则会关闭

    ?

    ? 因为北京站点被选中去掉了一个投票,只有一票,而佛山站点有两票,所以佛山站点可以形成群集,形成群集后佛山站点又自动去了一票,现在佛山站点也是奇数投票数

    ?

    技术分享

    ? 大家可以看到,这里的核心在于,群集选择去掉那个站点的投票,被去掉投票的站点,当发生投票时会被关闭,默认情况下群集会根据各个节点的状态变化,网络监测情况,不断的去调整票数,每次都会随机选择去掉投票站点的节点是谁,这有点像是每次都要随机抓一个倒霉蛋,反正都是抓,那么我们可不可以控制每次固定抓一个人呢,答案是可以的

    ?

    ? 通过LowerQuorumPriorityNodeID属性,我们就可以控制,在偶数节点下,如果要去掉一个节点的投票,那么始终去掉这个节点的,或者在两个节点的情况下,最终动态仲裁要随机去掉一个节点的投票,我们也可以指定,始终去掉另外一个节点的,来避免情况3的问题

    ?

    ? #查看当前LowerQuorum节点,默认是0,即每次发生变化时随机调整

    ? ?(Get-Cluster).LowerQuorumPriorityNodeID

    技术分享

    ?#获取节点ID,手动设置每次偶数投票数时丢弃HV04节点投票,每次都确保北京站点获胜

    ? ?(Get-Cluster).LowerQuorumPriorityNodeID=3

    技术分享

    当再次发生网络分区时可以看到,佛山站点关闭,北京站点存活下来,并自动调整为奇数投票

    技术分享

    技术分享

    群集应用也始终正常运行着

    技术分享

    以上为老王给朋友们上来的第二道菜和第三道菜

    ?

    ? ? 第二道菜我们在一个已知站点故障的情况下,手动取消了该站点的投票,阻止应用迁移到上面提供服务,这里我们是假设的一个没有分区的场景,因为两端还是可以通过心跳网卡互相做心跳检测的,我们在北京站点设置取消佛山站点的投票,佛山站点是可以知道的,如果是心跳网卡也发生了故障,即两边没办法进行进行心跳检测,这时候就要分情况来看,如果分区之前我们已经设置好了取消投票的站点,那么很好,群集会选择没被设置取消投票的站点启动,如果已经出现分区之后,那么只有强制启动需要的少数站点,启动之后再设置取消另外站点的投票,当另外站点上线时会以强制仲裁方为主。

    ?

    ? ? 第三道菜呢,默认情况下在动态仲裁的场景中,会随机为我们去掉一个节点的票数,我们可以使用LowerQuorumPriorityNodeID属性来手动下降一个站点,确保当网络分区发生时,始终是自己想要的站点获胜

    ?

    ? ?因此大家可以看出,在动态仲裁存在的场景下,我们几乎很少会用到强制仲裁,因为我们有很多新的技术可以选择,例如LowerQuorumPriorityNodeID,事前手动调整投票数,强制仲裁在一些场景下也或许有用,尤其是2012R2之后,阻止仲裁技术发生了改变,多数节点一方检测到少数节点一方存在仲裁会自动执行阻止仲裁操作,即确保承认强制仲裁一方为群集,与其群集数据库同步至最新后,才会启动自身群集服务,在之前2008时代,如果遇到强制仲裁的场景下,大多数时间都需要手动去执行阻止仲裁,否则会出现群集数据库覆盖等情况,到了2012R2则会自动帮助我们做这件事

    ?

    ? ?所以老王给大家的建议是,按照场景选择合适的技术,能通过手动调整投票解决或者通过LowerQuorumPriorityNodeID解决就尽量不用强制仲裁,2012R2之前使用强制仲裁需要考虑阻止仲裁问题,2012R2不需要考虑。

    ?

    ? ?实际上在动态仲裁启动的情况下,绝大部分场景动态仲裁都能帮助我们保证群集的可用性,始终让群集保持奇数投票,即便动态仲裁默认选择的站点你不满意,也可以用LowerQuorumPriorityNodeID,票数调整,强制仲裁等技术切换到满意的站点,像是以前50/50的脑裂分区场景,在动态仲裁的情况下是很难见到了,因此如果想看到脑裂场景最好的办法就是关闭动态仲裁

    ?

    ? ? 在第四道菜中,我们将模拟一个脑裂场景,北京佛山两个站点,关闭动态仲裁的情况下,禁用见证磁盘,两端出现网络分区时心跳网络和管理网络都已关闭,没办法进行站点间心跳检测

    ? ? ?

    #确认群集动态仲裁状态,默认为1,修改为0

    (Get-Cluster).DynamicQuorum = 0

    技术分享

    紧接着我们触发网络分区,修改HV03和HV04心跳网卡为其它网段,然后暂停路由服务器,让两端管理网络和心跳网络都不能互相做站点间的心跳检测,但是在各自站点内又都可以正常和AD通讯

    技术分享

    技术分享

    这时打开各个节点上面可以看到日志,提示群集网络已分区