Java架构师笔记-ZooKeeper到底是什么?

在传统的集群应用中,每个节点(服务器)的职责或功能都是一样的。而在ZooKeeper的集群中,分为三个角色,而且是各尽其责、相辅相成的。因为每个角色的职责不一样,所以就需要选举出一个Leader,作为ZooKeeper集群的领导者,负责对分布式系统全局的写操作,Leader选举是保证分布式数据一致性的关键所在。

角色

  • Leader 领导者
  • Follower 跟随者
  • Observer 观察者

Leader 领导者:

  1. 正常情况下只存在一个。
  2. 事务请求的唯一处理者,保证集群中事务处理的顺序性。

Follower 跟随着:

  1. 可以存在多个。
  2. 负责集群中的读请求,将事务请求转发给Leader处理。
  3. 参与Leader选举。

Observer 观察者:

  1. 可以存在多个或不存在。
  2. 与Follower的唯一区别在于不能参与Leader的选举。
  3. Observer的存在是为了不影响写性能的同时提高系统的吞吐量。

Leader选举的过程就是确定ZooKeeper角色的过程。当ZooKeeper未确定角色或处于选举过程中时,是不能对外提供服务的,服务器启动后会立即进入Leader选举,整个选举过程只会选出一个Leader,其余的会成为Follower,后面加入进来的ZooKeeper会成为Observer。ZooKeeper每个角色职责虽然不同,但是每个角色都会保存一份数据,并且这份数据是全局一致的。

 

Java架构师笔记-ZooKeeper到底是什么?_第1张图片

 

 

状态

ZooKeeper在服务器中,会存在四种状态。分别是LOOKING,LEADING,FOLLOWING,OBSERVING。

  • LOOKING 寻找状态 说明当前集群中没有Leader,需要进行Leader选举。
  • LEADING 领导状态 说明当前服务器ZooKeeper是Leader。
  • FOLLOWING 跟随状态 说明当前服务器ZooKeeper是Follower。
  • OBSERVING 观察状态 说明当前服务器ZooKeeper是Observer。

Leader选举发生的场景

  • 服务器启动时,需要进行Leader选举。
  • 服务器运行时,现有的Leader宕机或发生故障无法正常连接,需要重新进行Leader选举。

投票数据包

在Leader选举的过程中,每个参与投票的ZooKeeper会将自己的投票结果以广播的方式推送给其他参与者,推送的数据包包含一下数据:

  • myid:所推举的Leader的SID(服务器ID)。
  • zxid:事务ID (上篇文章已介绍)。
  • electionEpoch:逻辑时钟,用来判断多个投票是否在同一轮选举周期中,该值在服务端是一个自增序列,每次进入新一轮的投票后,都会对该值进行加1操作。
  • peerEpoch:被推举的Leader的Epoch,用于标记事务请求所属的轮次,如果不属于本次Leader选举的事务请求直接拒绝。
  • state:当前服务器的状态。

myid和zxid是决定投票结果的关键参数,使用(myid, zxid)来表示。ZooKeeper会优先比较zxid的只值,如果zxid的值相等则再比较myid的值, 数值越大在选举算法中的权重越大。

Leader选举过程

集群中,ZooKeeper至少要部署两台机器才能进行Leader选举,当所有集群的ZooKeeper都启动后,服务器间会进行通讯,每台机器都试图寻找Leader,此时ZooKeeper的状态都是LOOKING,由于此时还没有Leader,ZooKeeper会进入Leader投票选举过程:

假若现在有三台服务器Server1,Server2,Server3,他们的票分别为(1,3),(2,3),(3,2)。

  1. 第一轮投票:每台机器都会把票投给自己,推选自己为Leader,即Server1投票为(1,3),Server2投票为(2,3),Server2投票为(3,2),各个服务器会把自己的投票结果通知其他机器。
  2. 变更投票:收到其他机器的投票后,每台机器会根据一定规则来处理收到的其他机器的投票,并以此来决定是否需要变更自己的投票,这个规则也是整个Leader选举算法的核心所在。算法大致规则如下:
  • 如果收到的zxid大于自己的zxid,就认可收到的投票,把自己的票改为收到的票,并再次将该票发送出去。
  • 如果收到的zxid小于自己的zxid,那么坚持自己的投票,继续推选自己为Leader。
  • 如果收到的zxid等于自己的zxid,那么就对比两者的myid,如果收到的myid大于自己myid,那么就认可当前收到的票,并再次将该投票发送出去。
  • 如果收到的zxid等于自己的zxid,并且收到的myid小于自己myid,那么坚持自己的投票,继续推选自己为Leader。
  1. 确定Leader:每一轮投票结束,ZooKeeper都会进行票数统计,如果有一台机器收到了超过半数的相同的投票,那么这个投票对应的SID机器即会成为Leader。显示,上面机器中,Server2将成为Leader。

由上面规则可知,通常那台服务器上的数据越新(ZXID会越大),其成为Leader的可能性越大,也就越能够保证数据的恢复。如果ZXID相同,则myid越大机会越大。

ZooKeeper集群的数目最好为奇数

  • Leader选举采用Paxos算法,Paxos核心思想是当多数Server写成功,则任务数据写成功。如果有3个Server,则两个写成功即可;如果有4或5个Server,则三个写成功即可。
  • Server数目一般为奇数(3、5、7)如果有3个Server,则最多允许1个Server挂掉;如果有4个Server,则同样最多允许1个Server挂掉。

由此,我们看出3台服务器和4台服务器的的容灾能力是一样的,所以为了节省服务器资源,一般建议采用奇数个数部署。

你可能感兴趣的:(java)