天天看点

Zookeeper集群选举机制以及数据同步机制

Zookeeper集群选举机制以及数据同步机制

每天多学一点点~

话不多说,这就开始吧…进击的爆裂无球~

文章目录

    • Zookeeper集群选举机制以及数据同步机制
    • 1.前文
    • 2.Zookeeper的选举机制
    • 3.Zookeeper的数据同步机制
    • 4.关于Zookeeper的一些面试题
    • 5.结语

1.前文

国庆快乐,举国同庆~

之前写过zookeeper的集群搭建以及

Zookeeper的选举及运维可视化查看器及容灾,因有点时间没用Zookeeper,最近又深入学习了一下,研究研究它的选举机制和数据同步机制,以便以后复习用~

2.Zookeeper的选举机制

Zookeeper集群选举机制以及数据同步机制

投票机制说明:

选举分5个步骤:

  1. 初始化leader选举,投票

    给自己投票 myid zxid 0

  2. 每个服务器接受投票

    (1 0) (2,0) (3,0) >myid 谁最大谁就是leader

  3. 处理投票

    别的服务器 pk

  4. 统计投票
  5. 过半票数n=n/2+1;

    服务器状态变更

    Leader,其他票数低 f

依次启动三个zk,发现192.168.73.132是leader,其余两个是follower,这是因为

1: 三个服务器的myid分别是 1 2 3

2: 满足过半统计,即一共三个,启动第二个时候已经满足过半,所以第二个自动是leader

若反过来启动,即 按照 133-132-131的顺序,则133是leader,因为 133的myid最大,且启动132时候已经满足过半,所以133是leader

选举触发:

那么何时才会触发选举呢?

  1. 服务节点初始化启动
  2. 半数以上的节点无法和Leader建立连接

当节点初始起动时会在集群中寻找Leader节点,如果找到则与Leader建立连接,其自身状态变化follower或observer。如果没有找到Leader,当前节点状态将变化LOOKING,进入选举流程。

在集群运行其间如果有follower或observer节点宕机只要不超过半数并不会影响整个集群服务的正常运行。但如果leader宕机,将暂停对外服务,所有follower将进入LOOKING 状态,进入选举流程。

3.Zookeeper的数据同步机制

Zookeeper 的数据同步是为了保证各节点中数据的一致性,同步时涉及两个流程,一个是正常的客户端数据提交,另一个是集群某个节点宕机在恢复后的数据同步。

  • 客户端写入请求:

    写入请求的大至流程是,收leader接收客户端写请求,并同步给各个子节点。如下图:

    Zookeeper集群选举机制以及数据同步机制
    但实际情况要复杂的多,比如 client 它并不知道哪个节点是leader ,有可能写的请求会发给follower ,由follower在转发给leader进行同步处理
    Zookeeper集群选举机制以及数据同步机制
    客户端写入流程说明:
  1. client向zk中的server发送写请求,如果该server不是leader,则会将该写请求转发给leader server,leader将请求事务以proposal形式分发给follower;
  2. 当follower收到收到leader的proposal时,根据接收的先后顺序处理proposal;
  3. 当Leader收到follower针对某个proposal过半的ack后,则发起事务提交,重新发起一个commit的proposal
  4. Follower收到commit的proposal后,记录事务提交,并把数据更新到内存数据库;
  5. 当写成功后,反馈给client。
  • 服务节点初始化同步:

    在集群运行过程当中如果有一个follower节点宕机,由于宕机节点没过半,集群仍然能正常服务。当leader 收到新的客户端请求,此时无法同步给宕机的节点。造成数据不一致。为了解决这个问题,当节点启动时,第一件事情就是找当前的Leader,比对数据是否一致。不一致则开始同步,同步完成之后在进行对外提供服务。

    如何比对Leader的数据版本呢,这里通过ZXID(事物ID)来确认。比Leader就需要同步。

    ZXID说明:

    ZXID是一个长度64位的数字,其中低32位是按照数字递增,任何数据的变更都会导致,低32位的数字简单加1。高32位是leader周期编号,每当选举出一个新的leader时,新的leader就从本地事物日志中取出ZXID,然后解析出高32位的周期编号,进行加1,再将低32位的全部设置为0。这样就保证了每次新选举的leader后,保证了ZXID的唯一性而且是保证递增的。

    可以用运维四字命令查看,之前文章中也说过

    echo stat|nc 127.0.0.1:2181

    比如 :0x200000002 是当前的zxid,当leader变化时,高32变化,变成0x3 ,+1

    当数据变化时候,低32变化 +1 变成00000003

4.关于Zookeeper的一些面试题

  1. 如果leader 节点宕机,在恢复后它还能被选为leader吗?

    不能,因为会重新选举(选举期间暂停对外服务,直到新的leader产生),然后再次加进来,原来的leader会跟新的leader进行数据同步,变成follwer

  2. 现在有三个节点, zk1,zk2,zk3, zk2是leader,zk2挂了的同时在zk1进行了delete操作,现在把zk1 和 zk3也挂掉,再把三个节点全部起来,那么现在zk2还是leader嘛?

    不是。 因为你leader挂了之后,就会选举出新的leader(zk3),此时你在zk1中更新的数据(delete了一条数据)此时zk1和zk3的zxid是一致的,已经同步呢!

    (你老的leader(zk2)中的数据不是最新的,怎么好意思再给follower同步数据呢!)

    现在你又把zk1和zk3挂掉,再重启zk1,zk2,zk3,此时的选举,不再是一开始根据myid谁大谁就是leader,而是基于zxid(节点的事物ID)谁大谁就是leader,因为zk1更新了数据,此时它的zxid是最大的,所以启动后zk1是leader

    最后集群状态一致的话,整个集群的zxid都会一样

5.结语

世上无难事,只怕有心人,每天积累一点点,fighting!!!

继续阅读