脑裂问题(面试必备),值得收藏

脑裂问题(面试必备),值得收藏,第1张

脑裂问题(面试必备),值得收藏

转眼间再过一个月就到2022年了,临近年底有不少小伙伴问沐子,自己想要换工作,但是不知道是年前换好,还是年后换比较好呢?沐子一直的观点都是,换工作的时候只要你想清楚了,在现在的公司已经无法成长或者看不到希望时,到了非换不可的地步,那么只要有合适的下家的前提下,随时都可以换。从沐子多年的工作经验,以及跟身边一些资深HR沟通后,总结出来一些经验,那就是年前和年后都各有一个找工作的好时机,主要看求职者自身为换工作准备得是否充分。

我们在工作中可能很少碰到脑裂问题,但是面试官想要了解面试者的经历和解决复杂问题的能力,常常也会涉及到此类问题。小编主要以Redis、Zookeeper为例重点讲解脑裂问题和合适的解决方案,为粉丝们在面试中增加亮点。

一、 Redis集群脑裂

什么是redis的集群脑裂?

在哨兵架构中,redis的集群脑裂是某个master所在机器突然脱离了正常的网络,导致redis master节点跟redis slave节点和sentinel集群处于不同的网络分区,此时因为sentinel集群无法感知到master的存在,哨兵可能就会认为master宕机了,然后开启选举,将其他slave切换成了master,这个时候集群里就会有两个master,也就是所谓的脑裂。
出现集群脑裂后,如果客户端还在基于原来的master节点继续写入数据,那么新的master节点将无法同步这些数据,当网络问题解决之后,sentinel集群将原先的master节点降为slave节点,此时再从新的master中同步数据,将会造成大量的数据丢失。

解决方案

由于脑裂是由网络等原因造成的,除了提高网络、硬件等方法外,主要通过增加以下配置,改善出现脑裂而引发的数据丢失问题。

min-slaves-to-write 1 // 要求至少有1个slave
min-slaves-max-lag 10 //数据复制和同步的延迟不能超过10秒

如果一个master出现了脑裂,跟其他slave丢了连接,那么上面两个配置可以确保说,如果不能继续给指定数量的slave发送数据,而且slave超过10秒没有给自己ack消息,那么就直接拒绝客户端的写请求。这样脑裂后的旧master就不会接受client的新数据,最多就丢失10秒的数据,也就避免了大量长时间的数据丢失。

二、 Zookeeper集群脑裂
什么是Zookeeper的集群脑裂?

ZooKeeper是用来协调(同步)分布式进程的服务,提供了一个简单高性能的协调内核,用户可以在此之上构建更多复杂的分布式协调功能。下面以Zookeeper集群为例,讲解出现脑裂的情况。

从下图中可以看到,正常状态的时候,节点 5 作为主节点,其他节点作为备节点;当连接发生故障时,节点 1、节点 2、节点 3 形成了一个子集群,节点 4、节点 5 形成了另外一个子集群,这两个子集群的连接已经中断,无法进行信息交换。按照规则和算法,两个子集群分别选出了节点 2 和节点 5 作为主节点,此时整个系统就出现了两个主节点。这个状态违背了系统设计的初衷,两个主节点会各自做出自己的决策,整个系统的状态就混乱了。这时候整个系统就很混乱可能有一部分client已经通知到了连接到新的leader上去了,有的client仍然连接在老的leader上,如果同时有两个client需要对leader的同一个数据更新,并且刚好这两个client此刻分别连接在新老的leader上,就会出现很严重问题。


解决方案
要解决脑裂的问题,一般有下面几种方法:

1、zooKeeper默认采用了Quorums这种方式来防止"脑裂"现象。即只有集群中超过半数节点投票才能选举出Leader。这样的方式可以确保leader的唯一性,要么选出唯一的一个leader,要么选举失败。在zookeeper中Quorums作用如下:
【1】 集群中最少的节点数用来选举leader保证集群可用。
【2】 通知客户端数据已经安全保存前集群中最少数量的节点数已经保存了该数据。一旦这些节点保存了该数据,客户端将被通知已经安全保存了,可以继续其他任务。而集群中剩余的节点将会最终也保存了该数据。

假设某个leader假死,其余的followers选举出了一个新的leader。这时,旧的leader复活并且仍然认为自己是leader,这个时候它向其他followers发出写请求也是会被拒绝的。因为每当新leader产生时,会生成一个epoch标号(标识当前属于那个leader的统治时期),这个epoch是递增的,followers如果确认了新的leader存在,知道其epoch,就会拒绝epoch小于现任leader epoch的所有请求。那有没有follower不知道新的leader存在呢,有可能,但肯定不是大多数,否则新leader无法产生。Zookeeper的写也遵循quorum机制,因此,得不到大多数支持的写是无效的,旧leader即使各种认为自己是leader,依然没有什么作用。

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

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

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

综合分析,无论采取什么样的方案,状态决策都不可能做到任何场景下都没有问题,但完全不做高可用方案又会产生更大的问题,如何选取适合系统的高可用方案,也是一个复杂的分析、判断和选择的过程。

总之,上面通过Redis、Zookeeper为例重点介绍脑裂问题,列举了一些常用的解决方案,但是针对业务系统,永远都是具体情况具体分析,没有最好,只有最合适。

最后,如果我的文章对你有所帮助或者有所启发,欢迎关注公众号(微信搜索公众号:首席架构师专栏),里面有许多技术干货,也有我对技术的思考和感悟,还有作为架构师的验验分享;关注后回复 【面试题】,有我准备的面试题、架构师大型项目实战视频等福利 , 小编会带着你一起学习、成长,让我们一起加油!!!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5676308.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存