ZK的脑裂和选主

基础概念

  1. zxid:zk中的每一个更新操作都被封装成一个事务操作proposal,zxid是事务的唯一标识
  2. myid:zk中的每一台服务器都有自己的唯一id标识
  3. epoch:年代,leader每更换一次,年代值就加一
  4. ZK节点的状态:
    LOOKING: 处于选举状态;
    LEADING: 处于领导者状态;
    FOLLOWING:处于追随者状态;
    OBSERVING:处于观察者状态,此状态下的机器无权利投票

ZK的选主流程

ZK集群中只能有一个leader服务器,其他的服务器为follower或observer;

ZK开始选主的时机

  1. ZK集群启动时
  2. 当leader下线时;follower与leader保持心跳连接,当follower无法连接到leader时,会判断leader下线,将自身状态改为LOOKING
  3. 当follower下线导致leader领导的机器少于半数以上时;leader会检查自己lead的follower数量,当数量小于半数以上时,就会将自己挂掉,然后将自己的状态设置为LOOKING,开启重新选举

ZK选主过程

  1. 每一台服务器将自己的状态设置为LOOKING
  2. 每一台服务器投票给自己并广播自己的投票,投票内容为(epoch,zxid, myid) epoch为当前epoch值+1,zxid为自己处理的最大的事务id
  3. 每一台服务器将收到的票与自己持有的票进行PK,当接收的票epoch小于自己的epoch时,直接忽略;当接收的epoch大于自己的epoch时,更新自己的票的epoch并重新投票;当接收的epoch与自己的epoch相等,比较zxid,选择值较大的票,值较大的说明执行的事务多;如果zxid相等,比较myid,myid较大的服务器优先;之后选择胜出的票作为自己的选票并重新投出
  4. 统计每一台服务器获取的票数,当票数超过半数以上时,该服务器当选为leader,将状态更新为LEADING,其他服务器更新为FOLLOWING;否则重复2~3步

增加机器时

增加的机器状态一开始为OBSERVING,这种状态下的机器不具有投票的权利;直接以当前集群的leader作为leader即可。

脑裂

脑裂是指一个集群中出现了两个leader;出现脑裂后,对数据的写请求便可以发给两个不同的leader,从而导致数据一致性问题。

原因

一种常见的情况是,leader网络与部分follower断开,于是剩下的follower中选举出了新的leader。之后网络恢复,便出现了两个leader。

由此可见,脑裂情况是由于leader网络暂时与follower中断导致的,也就是出现了分区。根据CAP理论,出现了分区§之后,数据一致性©和可用性(A)之间只能选择一个。

zk的应对措施

ZK采用半数以上参与的方式杜绝脑裂情况的出现。简单说来就是ZK集群中必须有半数以上的机器存在,才能正常提供服务,包括选主,假如超过半数的机器宕机或网络中断,那么ZK集群就无法提供服务。

所以ZK选了一致性©而牺牲了可用性。但是ZK严格来说也并不是强一致性模型,ZK的写请求,只需要半数以上的机器被同步即算写入成功。
例如,ZK集群共有5台机器,那么至少要有3台在线才能保证半数以上,于是当有两台机器宕机时,服务便不可用了。

其他应对措施

  1. 加权机制:给所有的服务器分配权重,当超过一定权重值时即可进行选主。这样无法杜绝脑裂,但是可以增加对机器宕机的容忍性。
  2. 加锁机制:采用共享资源作为锁,例如redis,能够获取锁的服务器成为leader。

ZK节点数量最好是奇数,因为为了保证半数以上原则,5台机器只能允许2台宕机,6台机器也只能允许2台,多出的那一台并不能为系统的可用性做出贡献,所以没必要是偶数。

ZK如何处理请求

每一个ZK节点均可以处理读请求,但是写请求只能由leader节点处理;

  1. 当写请求发给follower节点时,follower节点会转发给leader节点
  2. leader节点接受写请求,将请求封装成一个事务proposal,分配唯一的zxid
  3. leader对事务进行处理之后,暂不提交,将事务发送到每一个follower的接收队列中
  4. follower从队列中取出事务执行,结束之后返回ACK。
  5. leader收到超过半数以上的follower的ack之后,提交事务并向客户端返回ack。同时向follower的队列中发送事务提交消息
  6. follower将事务提交

整体过程有点类似于二阶段提交,由leader作为协调节点。但是与二阶段提交不同的是,follower执行的事务与leader完全相同,都是完整的事务;而在分布式事务的二阶段提交中,每个服务仅执行事务中的一部分。

参考文献

https://www.cnblogs.com/ZhuChangwu/p/11622763.html
https://blog.51cto.com/kinglab/2447330

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值