首先我们知道高可用集群(HA),就要像其名字一样,高可用,那么它带给人们的就是24*365不间断运行,你很难想象如果哪天你正在银行存款,刚存了10W块钱进去,立刻再一查,发现竟然没存上?!这时候工作人员很抱歉的告诉你,由于银行内部的服务器刚才断线了0.5秒,导致你现在这笔存款不翼而飞了……那时候的你抓狂不?所以,高可用集群就是为了解决这个问题而存在的。
它最起码的要保证我们的服务器必须不能因为一台服务器的宕机而导致全盘皆输~
我们通过两台或者两台以上的服务器,来提供相同的服务,虽然两台机子都开着,但是同时工作的只有一台,此时正在工作的这个主机叫做主节点,而处于暂时检测随时准备替代主节点的那个主机叫备节点。这样,当主节点因为某些原因宕机之后,备节点会立刻接替主节点的任务,并且开始提供服务。
但是问题出现了,备节点如何去检测主节点呢?这时候我们就要用到心跳信息了。心跳信息,是主机通过向外发出一种信号,来证明自己还活着,以告知其他备主机只需要一直检测状态就行,而不需要来瓜分自己的资源。于是,备节点们通过主节点发出的心跳信息,来不断的确定主节点活着,自己不需要去工作。
当然,现实的问题总比我们设计好的要差很远,现实的问题就是,我们的主节点太忙了,它已经忙到没有时间去向外发送心跳信息了,于是一个新的问题出现了。备节点们很高兴的发现自己在规定的周期内没有检测到主节点发出的心跳信息,于是备节点们一个个高兴的准备启动了,以便能够接替主节点的所有任务。但是辛苦的主节点此时并没有任何问题,还正在欢快的忙碌着得时候,忽然发现了意见不妙的事情:自己的IP没了?服务也没了?用户在自己身上的连接瞬间被转移到其他的地方了!
主节点立刻就意识到了有人抢它的饭碗,愤怒的主节点立刻运行了一个机制再次把资源抢了回来。一抢回来不要紧,备节点依然因为主节点太忙而收不到主节点的心跳信息,于是,一个恶性循环开始了,主节点和备节点他们抢来抢去,直接导致我们用户的数据各种出错,各种无法读写。这种因为集群节点各行其事,导致资源哄抢的问题就叫做脑裂(Split-brain)。
毕竟这些节点主机都是人设计的,当我们发现问题,改正就行了。于是,我们设计出了一个机制节点级别的隔离机制。常用的叫做STONITH(Shoot The Other Node In The Head)爆头机制,一旦自己抢到资源,就立刻把其他节点主机的电源给掐断,让那个节点永远的不能跟自己抢夺资源。而这种机制就是专门来解决脑裂问题的。
当然,我们不能单纯的直接将电源切断,那样我们的当前节点正好宕机的话,那岂不是就再也没有备节点帮它提供服务了?所以我们又出了一种叫做资源级别的隔离机制,这种隔离只隔离服务器提供的资源,而不对服务器造成其他的什么损害。
但是,我们刚才的情况都仅仅针对了只有一个主节点和一从节点,如果有一堆节点怎么办?到底谁抢呢?难道是抢得快的抢的多,抢的慢的就抢的少么?呵呵,虽然备节点们一个个都像强盗一样在抢着各种资源,但是我们主节点可以规定,到底只允许哪个强盗在自己死后获得遗产,获得资源。而这种在自己死后控制资源转移的方式就叫做故障转移(failover)。
对于很多节点,他们都在提供不同的服务,不管哪个节点上的服务挂了,都会有其他的节点将其资源抢夺过来以保证服务的正常运行,那么到底挂掉多少节点,我们的服务才都不能运行了呢?这时候我们就需要一个机制,来计算整个多节点集群的工作是否处于一个正常状态,而计算的方法,我们采用投票制,每一个节点都握有票,要求集群的总体票数要超过半数才能运行,而我们投的票数叫做法定代表人数(quorum),一般必须是半数以上才能够确保一个多节点集群是处于正常状态的。而整个总管投票,决定投票的节点就叫做DC。
那么,一个完整的高可用集群到底是以什么结构来工作的呢?