脑裂(split-brain)
指在一个高可用(HA)系统中,当联系着的两个节点断开联系时,原本为一个总体的系统,分裂为两个独立节点,这时两个节点开始争抢共享资源,结果会致使系统混乱,数据损坏。
对于无状态服务的HA,无所谓脑裂不脑裂;但对有状态服务(好比MySQL)的HA,必需要严格防止脑裂。(但有些生产环境下的系统按照无状态服务HA的那一套去配置有状态服务,结果可想而知...)sql
如何防止HA集群脑裂
通常采用2个方法
1)仲裁
当两个节点出现分歧时,由第3方的仲裁者决定听谁的。这个仲裁者,多是一个锁服务,一个共享盘或者其它什么东西。数据库
2)fencing
当不能肯定某个节点的状态时,经过fencing把对方干掉,确保共享资源被彻底释放,前提是必需要有可靠的fence设备。vim
理想的状况下,以上二者一个都不能少。
可是,若是节点没有使用共享资源,好比基于主从复制的数据库HA,也能够安全的省掉fence设备,只保留仲裁。并且不少时候咱们的环境里也没有可用的fence设备,好比在云主机里。安全
那么可不能够省掉仲裁,只留fence设备呢?
不能够。由于,当两个节点互相失去联络时会同时fencing对方。若是fencing的方式是reboot,那么两台机器就会不停的重启。若是fencing的方式是power off,那么结局有多是2个节点玉石俱焚,也有可能活下来一个。可是若是两个节点互相失去联络的缘由是其中一个节点的网卡故障,而活下来的正好又是那个有故障的节点,那么结局同样是悲剧。
因此,单纯的双节点,不管如何也防止不了脑裂。bash
如何实现上面的策略
能够本身彻底从头开始实现一套符合上述逻辑的脚本。推荐使用基于成熟的集群软件去搭建,好比Pacemaker+Corosync+合适的资源Agent。Keepalived不太适合用于有状态服务的HA,即便把仲裁和fence那些东西都加到方案里,总以为别扭。服务器
使用Pacemaker+Corosync的方案也有一些注意事项
1)了解资源Agent的功能和原理
了解资源Agent的功能和原理,才能知道它适用的场景。好比pgsql的资源Agent是比较完善的,支持同步和异步流复制,而且能够在二者以前自动切换,而且能够保证同步复制下数据不会丢失。但目前MySQL的资源Agent就很弱了,没有使用GTID又没有日志补偿,很容易丢数据,仍是不要用的好,继续用MHA吧(可是,部署MHA时务必要防范脑裂)。网络
2)确保法定票数(quorum)
quorum能够认为是Pacemkaer自带的仲裁机制,集群的全部节点中的多数选出一个协调者,集群的全部指令都由这个协调者发出,能够完美的杜绝脑裂问题。为了使这套机制有效运转,集群中至少有3个节点,而且把no-quorum-policy设置成stop,这也是默认值。(不少教程为了方便演示,都把no-quorum-policy设置成ignore,生产环境若是也这么搞,又没有其它仲裁机制,是很危险的!)架构
可是,若是只有2个节点该怎么办?异步
可是若是你有不少双节点集群,找不到那么多用于凑数的节点,又不想把这些双节点集群拉到一块儿凑成一个大的集群(好比以为不方便管理)。那么能够考虑第三种方法。
第三种方法是配置一个抢占资源,以及服务和这个抢占资源的colocation约束,谁抢到抢占资源谁提供服务。这个抢占资源能够是某个锁服务,好比基于zookeeper包装一个,或者干脆本身从头作一个,就像下面这个例子。这个例子是基于http协议的短链接,更细致的作法是使用长链接心跳检测,这样服务端能够及时检出链接断开而释放锁)可是,必定要同时确保这个抢占资源的高可用,能够把提供抢占资源的服务作成lingyig高可用的,也能够简单点,部署3个服务,双节点上个部署一个,第三个部署在另一个专门的仲裁节点上,至少获取3个锁中的2个才视为取得了锁。这个仲裁节点能够为不少集群提供仲裁服务(由于一个机器只能部署一个Pacemaker实例,不然能够用部署了N个Pacemaker实例的仲裁节点作一样的事情。可是,如非无可奈何,尽可能仍是采用前面的方法,即知足Pacemaker法定票数,这种方法更简单,可靠。tcp
--------------------------------------------------------------keepalived的脑裂问题-------------------------------------------------------------------
1)解决keepalived脑裂问题
检测思路:正常状况下keepalived的VIP地址是在主节点上的,若是在从节点发现了VIP,就设置报警信息。脚本(在从节点上)以下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
|
2)曾经碰到的一个keepalived脑裂的问题(若是启用了iptables,不设置"系统接收VRRP协议"的规则,就会出现脑裂)
曾经在作keepalived+Nginx主备架构的环境时,当重启了备用机器后,发现两台机器都拿到了VIP。这也就是意味着出现了keepalived的脑裂现象,检查了两台主机的网络连通状态,发现网络是好的。而后在备机上抓包:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
|
3)预防keepalived脑裂问题
1)能够采用第三方仲裁的方法。因为keepalived体系中主备两台机器所处的状态与对方有关。若是主备机器之间的通讯出了网题,就会发生脑裂,此时keepalived体系中会出现双主的状况,产生资源竞争。
2)通常能够引入仲裁来解决这个问题,即每一个节点必须判断自身的状态。最简单的一种操做方法是,在主备的keepalived的配置文件中增长check配置,服务器周期性地ping一下网关,若是ping不通则认为自身有问题 。
3)最容易的是借助keepalived提供的vrrp_script及track_script实现。以下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|