ZK简介ZK=zookeeperZK是微服务解决方案中服务注册和发现的核心环境,是微服务的基石。ZK作为服务注册发现模块,并不是唯一的产品。目前业界认可的是Eureka和Consul。这里只说ZK。这个工具本身就是一个几兆字节的小压缩包。安装很傻,可以支持集群部署。背景在集群环境下,ZK的leader&follower的概念,ZK在节点异常时面临的问题以及如何解决。ZK本身是用java语言开发的,在Github上也是开源的,但是官方文档对内部的介绍很少,散落的博客很多,有些写的非常好。问题:在zookeeper选举算法中,超过半数的选票可以提供正常的服务。这是什么逻辑?ZK集群是单节点状态(每个节点只有一个状态),ZK的定位必须要求leader节点处于lading状态。looking:寻找leader状态,当前集群没有leader,进入leader选举过程。following:follower状态,接受来自leader节点的同步和命令。leading:领袖地位。observing:观察者状态,表名当前服务器为observer。ZKvotingprocessingstrategyvotinginformationincludes:Serverid,Zxidoftheelectedleader,SelectionEpochEpochjudgment,ownlogicEpochandSelectionEpochjudgment:greaterthan,lessthan,equalto.先查ZXID。ZXID较大的服务器优先作为领导者。如果ZXID相同,则比较myid。myid较大的服务器充当领导服务器。多数选举算法ZK中共有三种选举算法,分别是LeaderElection、FastLeaderElection和AuthLeaderElection。FastLeaderElection和AuthLeaderElection是类似的选举算法。唯一的区别是后者增加了认证信息。FastLeaderElection比LeaderElection更高效。后续版本只保留FastLeaderElection。理解:集群环境下启动多个节点时,ZK首先需要在多个节点中选择一个节点作为leader,并处于Leader状态,所以面临一个选举问题,同时选举规则是什么.《少数选举算法》:投票中得票数超过半数的节点获胜,即状态由looking变为leading,效率更高。用5台服务器解释一下思路:服务器1启动了,此时只有它的一台服务器启动了,它发送的Vote没有响应,所以它的选举状态一直是LOOKING;server2启动后,和第一个启动的server1一样,互相通信,交换选举结果。由于两者都没有历史数据,所以id值较大的服务器2获胜,但是由于没有超过一半的服务器同意选举它(本例中超过半数为3),所以服务器1和2继续维护寻找状态。服务器3启动。按照前面的理论分析,三个服务器都选了它,服务器3成为了服务器1、2、3的boss,因此成为了第二次选举的Leader。服务器4已启动。根据前面的分析,理论上服务器4应该是服务器1、2、3、4中最大的,但是由于已经有超过半数的服务器选择了服务器3,所以它只能接受更小的顺序兄弟。Server5启动,和4一样,作为小弟。假设5台服务器(3、4)中有2台挂了,leader也挂了:leader和follower之间有心跳检查,需要同步数据。Leader节点挂掉,整个Zookeeper集群将暂停对外服务,进入新一轮的Leader选举1)服务器1、2、5发现与leader失去联系,状态变为looking,开始anewvote2)服务器1、2、5分别启动Vote并广播投票信息,Epoch自增;3)服务器1、2、5分别处理选票,判断leader分别广播4)根据投票处理逻辑,选出1个(2票过半)5)各自服务器将6)重新为leader和follower状态提供服务。脑裂问题发生在集群中leader死亡,follower选举新的leader,原leader复活,因为ZK的overhalf机制允许一定的损失如果机器可以正常提供服务,当leader死亡判断不一致,就会出现多个leader。解决方案:ZK的过半机制也在一定程度上减少了脑裂的发生,至少不会同时出现三个leader。ZK中的Epoch机制(时钟)在每次选举时递增+1。通信时需要判断epoch是否一致。如果它比自己小,它将被丢弃。如果它比自身大,它将自行重置。Ifitisequaltoit,itwillbeelected;总结在日常的ZK运维中需要注意以上场景。极端情况下会出现问题,尤其是出现脑裂。可以采用:多数选举策略下的部署原则:服务器集群部署应该是奇数,比如:3,5,7,...,奇数最多leader配置的数量选择容易。ZK允许最大节点丢失数。原则是“保证一半以上选举正常”,多了就是浪费。详细的算法逻辑非常复杂,需要考虑很多情况。其中有Epoch(自增)的概念,分为:LogicEpoch和ElectionEpoch。每次投票判断每个投票周期是否一致等。
