Zookeeper(下面简称zk)作为一个工业级别的协调中心,有很多思想可供我们学习。

一、数据写入

zk的数据写入可以说是一个简单的2pc

  1. 首先向每个节点发送写入proposal,然后leader会手机各个节点的响应
  2. 如果半数以上响应了,开始发送commit请求

如果follower节点收到commit消息后,然后内部失败了怎么办呢?这个时候只有靠数据恢复?

答:

zookeeper注册信息 zookeeper注册过程_数据

二、准leader选举

首先要明确几个概念

  • myid:配置文件中配置的节点id
  • zxid:高32位是所属leader的纪元 epoch,就相当于皇帝的年号,低32位是个单调递增的值,每次有事务请求都会+1

选择其实从原理上来说是个很简单的过程,就是寻找最新的zxid的过程。下面就是投票规则

  1. 比较epoch(zxid的高32位)
  2. 比较事务id(zxid的低32位)
  3. 如果上面两个都相同,那么比较myid,谁大选谁。

在选举过程中,如果有节点获得超过半数的投票数,则会成为 Leader 节点。 集群中节点通信时为了避免重复建立连接,遵守一个原则:连接总是由 server id 较大的一方发起

我一直有个疑问,因为如果有个节点超过半数以上支持就会成为准leader,如果一个拥有最大事务的节点没有和这个leader比较过,那么这个准leader认为他是拥有最大事务的节点。 这合理吗? 而且在数据恢复阶段,这个拥有最大事务的节点还要数据回退吗?

答案:
其实他是每个节点都已经进行通信了,所以我的假设也根部不成立,下面是摘抄的一段话

每个server收到其它server发来的值后,进行判断,选择所保存的数据最新(zxid最大)、逻辑时钟最大,且在选举状态的id作为leader,并重新广播。来来回回几次之后,系统达成一致,得票多的为leader,leader被选出。

三、数据恢复阶段

上面选择的leader只是一个准leader,还必须要经过数据恢复阶段,才能广播消息,然后接受客户端请求。

数据恢复其实也是比较zxid,少的就补上对应的数据,这里一篇博客写的比较好

这里有一个疑问,既然准leader已经是最大的事务了,为什么还有回滚同步