ZooKeeper集群“脑裂” (3)

ZooKeeper 默认采用了 Quorums 这种方式来防止“脑裂”现象。即只有集群中超过半数节点投票才能选举出 Leader。这样的方式可以确保 Leader 的唯一性,要么选出唯一的一个 Leader,要么选举失败。在 ZooKeeper 中 Quorums 作用如下:

集群中最少的节点数用来选举Leader保证集群可用。

通知客户端数据已经安全保存前集群中最少数量的节点数已经保存了该数据。一旦这些节点保存了该数据,客户端将被通知已经安全保存了,可以继续其他任务。而集群中剩余的节点将会最终也保存了该数据。

假设某个 Leader 假死,其余的 followers 选举出了一个新的 Leader。这时,旧的Leader 复活并且仍然认为自己是 Leader,这个时候它向其他 followers 发出写请求也是会被拒绝的。

因为每当新 Leader 产生时,会生成一个 epoch 标号(标识当前属于那个 Leader 的统治时期),这个 epoch 是递增的,followers 如果确认了新的 Leader 存在,知道其 epoch,就会拒绝 epoch 小于现任 leader epoch 的所有请求。

那有没有 follower 不知道新的 Leader 存在呢,有可能,但肯定不是大多数,否则新 Leader 无法产生。ZooKeeper 的写也遵循 quorum 机制,因此,得不到大多数支持的写是无效的,旧leader即使各种认为自己是 Leader,依然没有什么作用。

ZooKeeper 除了可以采用上面默认的 Quorums 方式来避免出现“脑裂”,还可以采用下面的预防措施:

添加冗余的心跳线,例如双线条线,尽量减少“裂脑”发生机会。

启用磁盘锁。正在服务一方锁住共享磁盘,“裂脑”发生时,让对方完全“抢不走”共享磁盘资源。但使用锁磁盘也会有一个不小的问题,如果占用共享盘的一方不主动“解锁”,另一方就永远得不到共享磁盘。现实中假如服务节点突然死机或崩溃,就不可能执行解锁命令。后备节点也就接管不了共享资源和应用服务。于是有人在HA中设计了“智能”锁。即正在服务的一方只在发现心跳线全部断开(察觉不到对端)时才启用磁盘锁。平时就不上锁了。

设置仲裁机制。例如设置参考IP(如网关IP),当心跳线完全断开时,2个节点都各自ping一下 参考IP,不通则表明断点就出在本端,不仅”心跳”、还兼对外”服务”的本端网络链路断了,即使启动(或继续)应用服务也没有用了,那就主动放弃竞争,让能够ping通参考IP的一端去起服务。更保险一些,ping不通参考IP的一方干脆就自我重启,以彻底释放有可能还占用着的那些共享资源。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwxpxp.html