脑裂问题脑裂问题出现在集群中leader死掉,follower选出了新leader而原leader又复活了的情况下,因为ZK的过半机制是允许损失一定数量的机器而扔能正常提供给服务,当leader死亡判断不一致时就会出现多个leader 。
方案:
ZK的过半机制一定程度上也减少了脑裂情况的出现,起码不会出现三个leader同时 。ZK中的Epoch机制(时钟)每次选举都是递增+1,当通信时需要判断epoch是否一致,小于自己的则抛弃,大于自己则重置自己,等于则选举;
// If notification > current, replace and send messages outif (n.electionEpoch > logicalclock.get()) {logicalclock.set(n.electionEpoch);recvset.clear();if (totalOrderPredicate(n.leader, n.zxid, n.peerEpoch, getInitId(), getInitLastLoggedZxid(), getPeerEpoch())) {updateProposal(n.leader, n.zxid, n.peerEpoch);} else {updateProposal(getInitId(), getInitLastLoggedZxid(), getPeerEpoch());}sendNotifications();} else if (n.electionEpoch < logicalclock.get()) {if (LOG.isDebugEnabled()) {LOG.debug("Notification election epoch is smaller than logicalclock. n.electionEpoch = 0x" + Long.toHexString(n.electionEpoch)+ ", logicalclock=0x" + Long.toHexString(logicalclock.get()));}break;} else if (totalOrderPredicate(n.leader, n.zxid, n.peerEpoch, proposedLeader, proposedZxid, proposedEpoch)) {updateProposal(n.leader, n.zxid, n.peerEpoch);sendNotifications();}归纳在日常的ZK运维时需要注意以上场景在极端情况下出现问题,特别是脑裂的出现,可以采用:
过半选举策略下部署原则:
- 服务器群部署要单数,如:3、5、7、...,单数是最容易选出leader的配置量 。
- ZK允许节点最大损失数,原则就是“保证过半选举正常”,多了就是浪费 。
详细的算法逻辑是很复杂要考虑很多情况,其中有个Epoch的概念(自增长),分为:LogicEpoch和ElectionEpoch,每次投票都有判断每个投票周期是否一致等等 。在思考ZK策略时经常遇到这样的问题(上文中两块),梳理了一下思路以便于理解也作为后续回顾 。
推荐阅读
- 5GHz WiFi中的GHz是什么意思?
- 超实用的tomcat启动脚本实现
- 写了多年代码,你却不知道的程序设计的5个底层逻辑
- 22个超详细的 JS 数组方法
- 四种Python爬虫常用的定位元素方法对比,你偏爱哪一款?
- PHP中操作数据库的预处理语句
- 你应该知道的常用排序算法之快速排序
- LRU和LFU的区别
- 你知道Linux中用户们的密码藏在哪儿吗?
- 为什么我们要培养孩子的财商-?儿童财商培养
