群集节点监视
如果将群集资源类比为鸡蛋,那么群集节点类似于装有鸡蛋的篮子,篮子本身的完整决定着里面所装的鸡蛋的安全性。群集节点首先要决定自己是否存活,所以群集节点之间定期使用心跳来判断所有群集节点是否处于健康状态。群集的可用性目标因提供的服务的要求而异,不同服务等级要求的应用对故障恢复时间要求也不同,对健康检测严格要求也不同。同理,可用性要求越高的服务,对检测节点故障和采取后续行动进行恢复的速度越快,可用性要求不高的服务,对于故障恢复时间的容忍也相对要长。鉴于此,Windows Server群集初始具有两类严格程度不同的默认检测策略:
严格监控(AggressiveMonitoring):提供最快速的检测和恢复策略,保障最大的可用性。群集故障容忍度低,即使短暂的故障也要避免,以至于群集节点出现短暂的网络故障时,群集也会该节点上的应用迁出到正常的节点。
宽松监控(RelaxedMonitoring):提供相对宽松的检查策略,群集故障容忍度相对严格监控要高,允许短暂的群集节点故障。
严格监控和宽松监控都是相对的,可以使用两个具体的参数来测量,一个参数是心跳频率(Delay),一个参数是心跳失败阈值(Threshold)。
心跳间隔(Delay):定义在节点之间发送心跳检测信号的时间间隔,以秒为单位。
心跳失败阈值(Threshold) :定义在群集采取恢复动作之前能容忍的心跳次数失败的次数,比如心跳检测失败一次,群集不会立即采取恢复措施,而是继续发送下一个心跳检测信号,直到发送的次数达到设定值。
Windows Server不同版本的群集默认心跳频率和心跳失败阈值汇总如下:
参数 |
Windows Server 2012 R2 |
Windows Server 2016 |
最大 |
SameSubnetDelay |
1 秒 |
1 秒 |
2 秒 |
SameSubnetThreshold |
5 次心跳 |
10 次心跳 |
120 次心跳 |
CrossSubnetDelay |
1 秒 |
1 秒 |
4 秒 |
CrossSubnetThreshold |
5 次心跳 |
20 次心跳 |
120 次心跳 |
CrossSiteDelay |
N/A |
1 秒 |
4 秒 |
CrossSiteThreshold |
N/A |
20 次心跳 |
120 次心跳 |
可使用命令PS C:\>Get-Cluster |fl*Subnet* 查询跨子网和相同子网的心跳间隔和尝试阈值,命令输出的结果的心跳间隔的单位为毫秒,结果如下示例所示。
PS C:\> Get-Cluster |fl *subnet* CrossSubnetDealy :1000 CrossSubnetThreshold :20 PlumbAllCrossSubnetRoutes :0 SameSubnetDelay :1000 SameSubnetThreshold :10
调整心跳检测
严格的检查手段适用于一些高服务等级要求的应用,这些群集通常在一个高速连接的子网内。由于Windows Server 群集支持节点跨子网和站点部署,在群集节点相隔数公里而且的连接不怎么稳定的子网里,可以考虑稍微宽松的设置。同样,服务器硬件的冗余程度不断提高,操作系统也逐渐成熟,服务器节点本身的可用性已经非常可靠,服务器整体故障几率大为降低,这种情况下也可以按照实际情况将检测策调整得宽松点。可以使用如下PowerShell命令调整相同子网的心跳间隔,如下示例所示,将心跳间隔时间调整为2秒:
PS C:\> (get-cluster).SameSubnetDelay=2000
使用如下PowerShell命令调整相同子网的心跳失败阈值,如下示例所示,将心跳失败阈值设置为20次:
PS C:\> (get-cluster).SameSubnetThreshold=20
群集资源监视
除了要保证装鸡蛋的篮子的完整和可靠性,鸡蛋自身也会因各种因素变坏,因此群集除了要监视群集节点的健康状态,还需要监控构成群集及应用的资源健康状况。群集里通常有若干资源和资源组,群集运行并处理着不同的资源,有时候群集资源发生故障,虽然可以通过群集事件进行分析,但是对于深入的问题,必须通过分析DUMP日志这个“黑匣子”才能找到根本原因。如果你对群集资源故障了解不够深入解决起来会无从下手,但是作为维护人员,无论如何,需要为你的群集资源故障分析留一道门,这道门通往更加深入的资源监视通道,这道监视通道将帮助我们获取深入故障分析报告,将故障分析报告提交给微软让微软帮助定位问题所在。那么群集是怎样检测群集资源并报告事件给系统呢?接下来我们将带着这个疑问介绍群集的资源管理系统以及工作方式。
资源主机子系统
群集资源主机子系统(Resources Host Subsystem-RHS)负责监视群集资源,一个群集化的应用是以资源组形式存在的。群集里可以运行多个资源,这些资源同时被群集监视系统监控,群集监视系统除了RHS,还有资源控制管理器(Resource Control Manager,简称为RCM),RCM和RHS协调工作对完成群集资源的监视和操作,如图1所示。RHS和RCM都是群集服务的一部分,主要职责就是监视群集资源的状态。
图1 RHS和RCM
资源控制管理器
具体来说,RCM具有两个关键职责:一个是为群集服务执行故障转移机制和策略,另外的一个职责是建立和维护每个资源的依赖关系。以高可用文件服务器为例说明,群集文件服务器资源和磁盘以及访问名称、访问IP地址处于同一个资源组的依赖关系树,这个依赖关系树由RCM维护着,如图2所示。RCM维持单个资源和资源组的在线、离线、失败、在线挂起、离线挂起等各种状态,并负责资源组的移动、故障转移的操作。
图2 文件服务器资源依赖关系
资源监视器检测
为了保证群集应用正常工作,RHS时刻监视着资源情况并定期检查群集资源的健康状态。每个不同的资源的检查频率略有不同,检查频率由不同的群集资源DLL定义。RHS采用IsAlive和LooksAlive两个探测器进行周期性资源健康检测,LooksAlives检查比较粗糙,但是检查频率较高,默认情况下每5秒钟进行一次检查,而IsAlive检查更为仔细,但是检查频率较低,默认情况下每60秒检查一次。LooksAlives不停检查资源健康情况,一旦资源返回失败结果给LooksAlive,考虑到资源会出现“假死”状态,这时候,RHS会立即启用更全面的检查并调用 IsAlive检查资源是否真正出现问题。
在检测到群集资源故障后,RHS便会等待资源响应,如果在既定时间内没有响应,则会按照策略执行恢复操作。由于RHS只能判断资源不响应但是不能判断具体发生了什么故障,唯一的办法就是通过重启RHS进程尝试恢复资源。这个等待时间在群集资源的DeadLockTimeout属性里定义等待一次为300000毫秒,也就是5分钟,可以使用PowerShell命令查看和修改DeadLockTimeout值。
使用以下PowerShell命令查看群集资源的RHS等待时间。下面以Hyper-V群集(配置了群集复制代理角色)为例,命令输出的结果如下。
PS C:\> Get-ClusterResource |ft Name, ResourceType, DeadlockTimeOut
Name |
ResourceType |
DeadLockTimeout |
---- |
------------ |
---------- |
Cluster IP Address |
IP Address |
300000 |
Cluster Name |
Network Name |
300000 |
File Share Witness |
File Share Witness |
300000 |
Cluster-HRB |
Network Name |
300000 |
IP Address 192.168.1.5 |
IP Address |
300000 |
Hyper-V Replica Broker Cluster-HRB |
Virtual Machine Replication Broker |
300000 |
要修改某个群集资源的DeadlockTimeout时间可以参考如下命令,这个命令修改类型为Network Name的DeadlockTimeout为10分钟。
PS C:\> (Get-ClusterResourceType “Network Name”).DeadlockTimeout = 1000000
虽然可以任意定义DeadlockTimeout时间,但是不建议将这个值改成比5分钟更大,试想IsAlive和LookAlive检查时间往往在几百毫秒内完成,而DeadlockTimeout的时间为5分钟,已经大大超出了IsAlive和LookAlive检查时间。
除此以外,群集为了做到准确监控,默认启用了一层保护保护机制,当群集发送结束RHS指令时,不会立即重启RHS进程,而是等待4次DeadlockTimeout时间(20分钟),如果资源仍然没有响应才采取结束RHS进程的措施。如果RHS进程在等待4次(20分钟)资源仍未响应,群集判断服务器可能出现严重的问题,进而强制重启群集节点。
最重要的是,RHS产生Windows 错误报告给群集系统并把错误写入DUMP文件,因为不同应用的群集涉及的群集资源也是千变万化的,一般出现严重的问题需要进一步的分析,笔者曾经遇到群集节点发生 I/O Request Packet 队列过多导致服务器使用Bugcheck自动重启的情况,最后通过分析DUMP发现了问题的根本原因,因此说,RHS打开了一扇通往深入分析群集的门。
资源监视器调整
群集将资源DLL加载到资源主机监控进程(RHS.exe),RHS进程是循环使用的。早期的设计里,默认情况下所有的资源在一个RHS进程里运行,这种情况的问题是如果一个资源故障,那么整个RHS进程和所有由这个RHS加载的资源都会出现故障。考虑到这种设计的不足,在后期Windows Server 群集里做了改良,重要的资源都加载到各自独立的RHS进程里。但是仍然有可能不同的群集资源加载到了同一个RHS进程里,如果多个资源共享一个RHS进程,那么某个资源出现故障时,群集会重启RHS进程,这样其他加载到RHS进程的正常资源也会跟着重启。
为了避免这类问题发生,可以酌情为不同的资源分配独立的资源监视器RHS进程。在群集资源里,有一个属性代表着使用独立还是共享的RHS进程,这个属性是SeparateMonitor。这个属性定义为0或者1,0和1代表False和True,定义为0,代表群集资源使用共享的RHS进程,定义为1,代表群集资源使用独立的RHS进程。
可使用Get-ClusterResource查看哪些资源使用独立的RHS进程监控。下面以两个SQL Server数据库群集为例,运行如下命令查看RHS监视器情况。
PS C:\> Get-ClusterResource | ft name, SeparateMonitor, MonitorProcessID
Name |
SeparateMonitor |
MonitorProcessID |
---- |
------------ |
---------- |
Cluster Disk 1 |
False |
3144 |
Cluster Disk 2 |
False |
3144 |
Cluster IP Address |
False |
3020 |
Cluster Name |
False |
3020 |
File Share Witness |
False |
3020 |
SQL IP Address 1(MSSQLSERVER) |
False |
3020 |
SQL IP Address 2(Test) |
False |
3020 |
SQL Network Name(MSSQLSERVER) |
False |
3020 |
SQL Network Name(Test) |
False |
3020 |
SQL Server |
True |
3188 |
SQL Server(Test) |
True |
3224 |
SQL Server Agent |
True |
3272 |
SQL Server Agent(Test) |
True |
3308 |
可以使用Get-ClusterResource修改资源使用独立的RHS进程监控。下面以数据库群集磁盘资源为例,将群集磁盘Cluster Disk1设置为使用独立的监视器,运行如下命令设置Cluster Disk 1使用独立的RHS监视器。
PS C:\> (Get-ClusterResource “Cluster Disk 1”).SeparateMonitor = 1
再次运行如下命令查看群集资源监视器情况
Name |
SeparateMonitor |
---- |
------------ |
Cluster Disk 1 |
True |
Cluster Disk 2 |
False |
Cluster IP Address |
False |
Cluster Name |
False |
File Share Witness |
False |
SQL IP Address 1(MSSQLSERVER) |
False |
SQL IP Address 2(Test) |
False |
SQL Network Name(MSSQLSERVER) |
False |
SQL Network Name(Test) |
False |
SQL Server |
True |
SQL Server(Test) |
True |
SQL Server Agent |
True |
SQL Server Agent(Test) |
True |
要注意的是,如果群集资源过多的情况下启用为每个资源配置独立的RHS进程,将会导致系统里同时运行多个RHS进程,因此会过多开销系统内存和CPU资源。而且群集已经可以把有问题的资源隔离加载到独立的RHS进程,从而避免有问题的资源影响到其他健康的资源,通常建议为群集资源保持默认设置。