前言:
该文章耗费作者大量时间,转载声明转http://anyisalin.blog.51cto.com/
介绍:
该文章是我学习马哥的HA集群课程之后所写,基本凭自己的记忆编写,若有错误,麻烦回复指出,谢谢!
为什么要提供一个服务的高可用?
高可用(High Available)顾名思义是提高一个服务的可用性,在生产环境当中,如果对外提供服务的主机出现故障是致命的,可能会造成很大损失,我们需要提供一个解决方案,在服务器出现故障时能迅速将服务器上运行的服务转移到其他备用的节点,并让其继续运行对外提供服务.
服务高可用该如何实现?
在实现服务高可用的时候有许许多多的问题需要,例如备用节点如何知道主节点出现故障?、备用节点如何接管资源?、如果主节点没故障,备用节点认为其故障而强制接管其资源怎么办?诸多问题需要解决.那么我们到底该怎么实现高可用集群呢?我们需要了解一些关于高可用集群的原理.
实现原理
在高可用集群的各节点中定义了一个抽象层,信息传递层(Messaing Layer),用来传递集群之间的事务(Transaction)信息.事务信息中包含了节点的心跳信息(是否在线),节点的主机名、IP等一系列信息.当然光有Messaging Layer并不能实现一个集群的高可用.这里我们介绍一个概念
一个服务要是想实现高可用需要两个条件:
Messaging Layer
实现Messaging Layer的软件有很多,例如corosync,heartbeat...
ha-aware/CRM
ha-aware: 是指一个服务本身具备高可用能力,能够通过API调用Messaging Layer传递的信息来提供高可用
CRM: 全称Cluster Resource Manager,集群资源管理.能够通过Messaging Layer传递的信息,对集群中各节点的资源进行相应处理
CRM需要在集群各节点中选举出DC(Designated Coordinator)指定调解员对集群上的资源进行计算,计算出资源更适合运行在哪个节点中.
DC中又包含两个引擎来处理不同的事情
PE: Policy Engine 用来计算
TE: Transaction Engine 用来指挥资源的转移
TE通过指挥LRM(Local Resource Manager)来实现资源转移
FailOver: 故障转移,运行资源的节点出现故障时将资源转移到其他节点
FailBack: 转回,节点重新上线后将原来的资源转回
资源:
资源是运行在集群上的服务,IP等一系列可以被CRM所管理的,能够在节点出现故障时收到LRM的指令做出相应的动作
例如: 我们要提供一个httpd服务的高可用需要的资源: VIP: 对外提供服务的IP地址
httpd: httpd服务
但是资源应该在那个节点中运行,是否能够运行在某个节点上都是通过Resource Constraint来定义的
Constraint: 资源约束分为三个类别
Location: 位置约束
使用分数来定义资源是否倾向于运行在此节点上
INF: 倾向于运行在此节点
-INF: 不倾向于运行在此节点
Colocation: 排列约束
使用分数来定义资源是否能够同时运行在一个节点上
INF: 能够同时运行在一个节点上
-INF: 不能同时运行在同一节点上
Order: 顺序约束
定义资源启动|关闭的顺序
如果主节点出现故障,备用节点接管其资源来提供服务,一段时间后,主节点重新上线,那么集群资源是否会重新回到主节点,这里我们就要解释一下Resource Stickiness
Resource Stickiness: 资源粘性,定义一个资源是否倾向于留在此节点.
相信大家都了解,位置约束是定义资源是否倾向运行在此节点,那么当同时定义了资源粘性和资源约束的时候,资源到底应该运行在哪个节点上呢,我们来看一个案例
例子:
节点: node1.anyisalin.com,node2.anyisalin.com
节点资源: httpd
默认资源粘性为100,httpd对node1的位置约束的分数值为INF,对node2的位置约束的分数值为200
原本httpd服务运行在node1上,有一天node1突然出现了故障,资源理所应当转移到node2上,运行了一段时间之后,node1重新上线,我们来计算一下httpd服务到底应该运行在哪个节点
node1: 对于httpd的位置约束分数值为INF,httpd对其资源粘性值为100 node2: 对于httpd的位置约束分数值为200,httpd对其资源粘性值为100 node1=100+INF node1=INF node2=100+200 node2=300 node1>node2 故httpd服务应该转移回node1
RA: Resource Agent资源代理,其实就是定义成集群资源的脚本,能够LRM的发送的指令来实现对集群资源的管理
RG: Resource group资源组,若干个集群资源组成的组,同进同退
RA Classes:
LSB: Linux Standard Base
/etc/init.d/下的所有脚本就是LSB标准的,至少支持statr,status,restart,stop四个指令
OCF: Open CLuster Framework
一个支持更多指令的标准,更加的灵活
Resources Classes:
Primitive:
主资源类型,同一时刻集群中只能有一个节点运行主资源
Clone:
克隆,将主资源克隆,同一时刻必须运行在指定的节点上
Group:
组,将若干个主资源归类为组,当成一个单位同进同退
Master/Slave:
特殊的Clone资源,只能运行两份,一个节点为主节点,一个节点为备份节点
资源隔离:
什么时候需要资源隔离?
当集群节点无法有效获取其他节点信息,以至于抢占资源
严重后果: 抢占存储资源,导致分区崩溃
解决方案: 资源隔离
资源隔离:
节点级别:
STONITH: 使用STONITH设备强制关闭|重启节点
资源级别:
使用FC交换机,实现在存储资源级别隔离节点访问
我们可能还需要考虑一种情况,在节点发生故障时候,不能获取其他节点信息,节点是如何得知到底是自己出现故障,还是其他节点故障?
这里我们可以使用ping node,或者仲裁磁盘来解决了.
ping node: 当节点不能获取另一个节点信息时,ping提供的第三方节点,如果能ping通,fence另一个节点
仲裁磁盘: 集群中各节点在运行的时候,同时向同一共享存储中写入数据,当某节点不能获取另一个节点信息时,查看仲裁磁盘另一个节点是否还在写入数据,如果没有,fence另一个节点
在一些特定场景,我们在高可用集群中可能要使用多于2个的节点,那么我们需要考虑更多问题了
一个节点出现故障该如何判定自己应该自杀还是fence其他节点?
quorum: 法定票数
多节点集群中,每一个节点都具有相应的法定票数
node1 不能获取其他节点信息
node2 <--> node3 node2和node3能够获取对方信息
假定每个节点的票数都为1票
node2+node3 > 3/2 node1应该根据资源策略才做出相应动作
资源策略: Without_quorum_Policy 不具有法定票数
freeze: 不再接受新的请求,已连接的不便
stop: 停止集群服务
ignore: 忽略,继续运行集群服务