ZooKeeper(二)

上篇

六. Zookeeper 分布式


🌻 【选举机制】

在Zookeeper集群刚启动的时候,所有的节点(服务器)都会进入选举状态,所有节点都会推荐自己成为leader。每一个节点都会将自己的选举信息发送给其他节点,节点之间会进行比较,经过多轮比较,最终胜出的节点会成为leader。

  1. 选举信息

    1. 节点的最大事务id

      最大事务id越大,说明该节点干的事最多

    2. 选举编号 - myid

    3. 逻辑时钟值 - 确定轮数

      经过一轮选举可能选不出leader,需要经过多轮选举。逻辑时钟值就是来记录比较轮数的。该值与选举规则并不相关,只用于记录轮数。

  2. 比较原则

    1. 先比较两个节点的最大事务id:"谁大谁赢"

    2. 如果事务id一致,比较myid:"谁大谁赢"

    3. 进行下一轮比较。

    4. 如果一个节点胜过一半级以上的节点,就会被选举成为leader。过半性

  3. 当一个Zookeeper集群已经选出了leader,为了集群的稳定性,无论新添的节点事务id或者myid是多少,都只能称为follower。除非leader宕机,重新选举。

  4. 宕机后的原leader节点重新连接上,会将他作为一个新节点称为follower。

  5. 如果集群中出现多个leader,这种现象称之为脑裂。脑裂产生的条件:

    1. 集群产生分裂(网络故障)
    2. 分裂出去的集群产生了选举。

    预防脑裂:在Zookeeper集群中,如果存活的节点个数不足一半,则剩余的节点不选举也不对外服务(过半性)。可以理解为这些节点处于休眠状态。

  6. Zookeeper中的节点个数一般是奇数个,最少是3个。(一个不是集群,两个不过半,至少3个)

  7. Zookeeper会对每一任leader进行编号,这个编号称之为epochid,该id自增。一旦Zookeeper发现存在一个以上的leader,会将epchid较小的节点改成follower。

  8. Zookeeper集群中的节点状态

    1. voting - 选举

    2. follower - 追随者

    3. leader - 领导者

    4. observer - 观察者

      在集群中,一个节点一旦没设置为observer,那么这个节点的状态就不再改变。其及不参与选举,也不参与投票(原子广播),但是会监听选举和投票结果,然后根据结果产生对应的操作。- observer是没有选举权的follower。

      一个集群中,会将90%~97%的节点设置为observer,目的是为了提高选举和投票效率,减小网络影响。

      在Zookeeper中,observer的存活与否不会影响集群对外服务。例如“假设一个集群中有21个节点,其中有一个leader,6个follower,14个observer,那么即使14个observer全部宕机,集群依然对外服务。凡是如果4个follower宕机,集群就会停止对外服务 - 过半原则是有投票权的节点。

 

七. ZAB协议


ZAB(Zookeeper Atomic Broadcast)协议是一套专门为Zookeeper设计的进行原子广播崩溃恢复的协议。其基于2PC算法来进行设计,利用了过半性+PAxos算法进行了改进。

1. 原子广播

  1. 作用:保证节点之间数据的一致性,即在Zookeeper中,访问任意一个节点获取到的数据都是相同的。

  2. 基于2PC算法来进行设计,利用了过半性+PAxos算法进行了改进。实际过程中要么是请求提交,要么是请求中止,核心思想是一票否决

    2PC - Two Phase Commit - 二阶段提交。

    1. 请求阶段:协调者收到请求之后不能立即决定执不执行该请求,而是发给每一个参与者,等待参与者的反馈消息。
    2. 提交阶段:如果协调者收到所有参与者返回的yes,那么协调者就会命令每一个参与者执行这个请求。
    3. 中止阶段:如果协调者没有收到所有参与者返回的yes,那么协调者就会命令所有参与者放弃这个请求。如果一段时间内没有收到某个参与者反馈,将默认为no。

    2PC算法设计和实现过程相对简单,但是非常受外界环境影响,对网络环境的容错性相对较差。集群越大,失败的概率越高。

    【改进之后】

    1. leader收到请求后,会先将这个请求记录到本地的日志文件:log.xxxx中。其存储位置由配置文件中的dataDir。如果记录失败,直接报错;如果记录成功,leader会把请求(不止一个)放到队列,发给每一个follower。
    2. follower收到队列之后,也会将请求队列记录到本地的日志文件log.xxxx中。如果记录成功,则认为请求可以执行,反馈leader一个yes;如果记录失败,则follower认为请求不能执行,返回No。
    3. 如果leader收到半数以上的yes,就会要求所有follower执行,反之会要求所有follower删除之前的记录(回滚)。
  3. 返回no的可能原因:(理应返回yes)

    1. 文件被占用——非大问题,Zookeeper会自动考虑新增
    2. 磁盘满了或磁盘损坏——Zookeeper解决不了。
  4. 如果follower记录失败,leader却要求执行这个请求,follower会给leader发请求。leader收到请求之后,会把操作放到队列中发送给follower,follower会再次试图记录日志再次执行;如果再次记录失败,又会重复发送请求。如果在维护集群的时候发现follower频繁发送请求给leader,则说明无法记录日志。

2. 崩溃恢复

在Zookeeper集群中,当leader丢失的时候,集群不会停止服务而是会选举产生一个新的leader,这个过程称之为崩溃恢复。

  1. 作用:保证集群的可用性,避免单点故障。
  2. 当一个节点重新连入集群,该节点会先找到自己的最大事务id,然后会给leader发送一个请求,leader收到请求之后会比较事务id是否一致,如果不一致,leader就会将所缺失的事务放到队列中返回给这个节点要求补齐。
  3. Zookeeper会对每一任的leader分配一个递增的epochid。当leader上任之后,这个leader会将自己的epochid发给每一个follower,follower收到之后会存储到本地文件acceptedEpoch中。
  4. 在集群中,事务id实际是由64位二进制(16位16进制)数字组成,其中高32位是Epochid,低32为是实际的事务id。(高位的0会省略)

 

八. 总结


Zookeeper有以下特性,分别体现在不同地方。

  1. 过半性——过半选举,过半服务,过半操作。
  2. 数据一致性——访问任意一个节点,获取的数据都是相同的。
  3. 原子性——一个请求到了Zookeeper上之后,要么所有节点都执行,要么都不执行。
  4. 可靠性——保证集群的高可用。
  5. 顺序性——leader按照什么顺序接受的请求,follower就会按照什么顺序执行请求。【内部传递采取队列】
  6. 实时性——在网络条件较好的情况下可以实时监控Zookeeper变化。
posted @ 2020-06-23 10:02  仰观云  阅读(129)  评论(0编辑  收藏  举报
Live2D