Zookeeper详解
成员:
- leader(接受所有的事务请求)
- follower(历史事务集合)
- observer(不参与过半选举,提高读性能)
ZAB协议:
在ZAB协议中,每个事务都有一个编号ZXID(一个64位的数字),ZXID由两部分组成,高32位是epoch,低32位是递增计数器
epoch: 选举周期
计数器: 随事物的到来递增
是为Zookeeper专门设计的一种支持崩溃恢复的消息广播协议.ZAB协议只允许有一个主进程接受客户事务请求并处理,即leader.leader收到事务请求后,将事务转化位proposal,由于leader会为每个follower创建一个队列,将事务放入队列中,便可以保证事务的顺序性.之后会在队列中顺序的向其他节点广播该提案,follower收到后将以事务的形式写入到本地日志,并向leader发送反馈ACK.leader收到半数以上的follower的响应后,leader会向其他节点发送commit消息,同时提交该提案.
消息广播:
消息广播过程使用的是一个原子广播协议,类似于一个二阶段提交过程. 将事务请求转化为Proposal,发送给集群中所有的机器,然后收集投票,进行事务提交. 不过与二阶段不同的是,半数以上follower响应就可以提交事务,而不用等待每一个都响应. 不会有单点问题,加入leader出问题,所有的follower会抛弃leader,进行重新选举,不会一直等待.
崩溃恢复(leader选举和数据同步):
ZAB协议需要保证已经被leader提交的事务最终被所有的机器提交;
ZAB协议需要保证丢弃那些只在leader上提交的事务;
leader选举: 为了保证以上两点,选择ZXID为最大的节点可以解决上述问题.
数据同步: 为每个follower创建一个队列, leader将各个follower没有提交的事务写入各个队列, 并发送给各个follower. follower将事务同步后leader将其加入真正可用的follower列表.
leader重新选举的条件: leader宕机或发生故障, 集群中有少于 一半的节点与当前leader保持连接.
故障恢复,算法描述:
- 每个follower会将自己最后接受的事务proposal的epoch发送给准leader
- 准leader在收到所有follower的epoch中选出最大值, 在此基础上加一形成新的选举周期, 发送给所有的follower
- follower收到后会更新自己的epoch, 并反馈给准leader一个ACK, 同时携带所有事务集合
- 准leader收到所有的历史事务集合后, 会形成初始化事务集合
故障恢复, 同步:
- 准leader将初始化事务集合(上一步中最长的历史事务集合)发送给集群中所有的follower, 紧跟着发送一个commit, 表示该事务已经被提交
- follower收到后对于其中每一个事务, follower都会接受, 并反馈给leader, 表示已经接受所有的事务
- leader收到所有的来自过半以上的follower的反馈后, 就会向所有的follower发送commit消息
Leader选举(fastleaderelection算法)
- 每个节点除ZXID, 还有一个myid, 生成的选票为(myid, zxid), myid类似于唯一标识
- 两种情况: 启动时选举和运行时选举
- 外部投票: 其他服务器发来的投票
- 内部投票: 服务器自身当前的投票
- 选举轮次: leader周期, 即可理解位epoch
- PK: 比较外部投票和内部投票, 确定是否变更内部投票
启动时leader选举
- 每个节点初始化自己的选票,(myid, ZXID), 每个server发出一个投票
- 接受来自各个服务器的投票, 检查该投票的有效性, 是否位本轮投票, 是否来自LOOKING状态的服务器
- 处理投票, 进行PK, 优先检查ZXID, ZXID比较大的优先作为leader, 如果ZXID相等, 比较myid, myid比较大的作为leader服务器, 更新自己的投票信息, 重新发出
- 统计投票, 每次投票服务器都会进行统计, 判断是否已经有过半的机器接收到相同的投票信息
- 改变服务器状态, 一旦确定leader, 如果是follower就会变更为FOLLOWING, 如果是leader, 就会变更为LEADING
运行时leader选举
- 变更状态, leader挂了后, 余下的所有非observe服务器都会将自己的服务器状态变更为LOOKING, 进入leader选举流程.
然后同上面的12345

浙公网安备 33010602011771号