ZooKeeper 集群

集群

集群角色

通常在分布式系统中,构成一个集群的每一台机器都有自己的角色,最常见的集群模式就是Master/Slave模式(主从模式),在这种模式中,通常Maste服务器作为主服务器提供写服务,其他的Slave服务器从服务器通过异步复制的方式获取Master服务器最新的数据提供读服务。

但是ZooKeeper并没有沿用传统的主从模式,而是引入了LeaderFollowerObserver三种角色,如下图所示:

ZooKeeper集群中的所有机器通过一个Leader 选举过程来选定一台称为Leader的机器,Leader既可以为客户端提供写服务又能提供读服务。除了Leader外,FollowerObserver都只能提供读服务。Follower和Observer唯一的区别在于Observer机器不参与Leader的选举过程,也不参与写操作的“过半写成功”策略,因此Observer机器可以在不影响写性能的情况下提升集群的读性能。

  • Leader:为客户端提供读和写的服务,负责投票的发起和决议,更新系统状态。
  • Follower:为客户端提供读服务,如果是写服务则转发给Leader。在选举过程中参与投票。
  • Observer:与Follower工作原理基本一致,唯一的区别是Observer不参与任何形式的投票。Observer主要用来在不影响写性能的情况下提升集群的读性能,是ZooKeeper3.3中新增的角色。

ZooKeeper用以下四种状态来表示各个节点

  • LOOKING:竞选状态。
  • LEADING:Leader状态。
  • FOLLOWING:Follower状态。
  • OBSERVING:Observer状态。

选举

Leader选举是ZooKeeper中最重要的技术之一,也是保证分布式数据一致性的关键所在。

当ZooKeeper集群中的一台服务器出现以下两种情况之一时,就会开始进入Leader选举

  • 服务器初始化启动
  • 服务器运行期间无法和Leader保持连接

在介绍选举之前,首先介绍三个重要参数

  • 服务器ID(myid):编号越大在选举算法中权重越大。
  • 事务ID(zxid):值越大说明数据越新,权重越大。
  • 逻辑时钟(epoch-logicalclock):同一轮投票过程中的逻辑时钟值是相同的,每投完一次值会增加。

服务器启动时期的选举

ZooKeeper集群初始化时,当满足以下两个条件时,就会开始进入Leader选举流程:

  • 集群规模至少为2台机器
  • 集群内的机器能够互相通信

如上图,选举流程如下:

  1. 每个服务器会发出一个投票:由于是初始化状态,每一个节点都会将自己作为Leader来进行投票,每次投票的内容包含:推举服务器的myid(在集群中的机器序号)和ZXID(事务ID),以(myid, ZXID)的形式表示。初始化阶段每个节点都会将票投给自己,然后将这个投票发给集群总其他所有机器。
  2. 接受来自各个服务器的投票:每个服务器都会接收来自其他服务器的投票,在接收投票后首先会判断该投票的有效性,如是否为本轮投票(逻辑时钟)、是否来自LOOING状态的服务器。
  3. 处理投票:在接收到来自其他服务器的投票后,针对每一个投票,服务器都需要将别人的投票和自己的投票进行PK,PK规则如下
    • 优先检查ZXID,ZXID较大的优先作为Leader。
    • 如果Leader相同则比较myid,myid较大的作为Leader。
  4. 统计投票:每次投票后,服务器都会统计所有投票,判断是否已经有过半的机器接收到相同的投票信息。当票数达到半数以上时,此时就认为已经选出了Leader。
  5. 改变服务器状态:一旦确认了Leader,则每个服务器开始改变自己的状态。如果是Follower则更改成FOLLOWING;如果是Observer则更改成OBSERVING;如果是Leader则更改成LEADING;

服务器运行时期的选举

在ZooKeeper集群正常运行中,一旦选出一个Leader,那么所有服务器的集群角色一般不会再发生变化——也就是说Leader服务器将一直作为集群的Leader,即使集群中有非Leader机器挂了或者是有机器加入集群也不会影响Leader。但是一旦Leader所在的机器挂掉,那么此时整个集群将暂时无法对外服务,马上进入新一轮的Leader选举。

服务器运行期间的Leader选举和启动时期的Leader选举基本是一致的,只增加了一个变更状态的步骤,流程如下:

  1. 变更状态:当Leader挂了之后,剩下的所有非Observer服务器都会将自己的服务器状态变更为LOOKING,然后开始进入Leader选举流程。
  2. 每个服务器会发出一个投票
  3. 接受来自各个服务器的投票
  4. 处理投票
  5. 统计投票
  6. 改变服务器状态

集群的机器数量

为什么ZooKeeper提倡集群的机器数量最好要做奇数台呢?

ZooKeeper 集群在宕掉几个 ZooKeeper 服务器之后,如果剩下的 ZooKeeper 服务器个数大于宕掉的个数的话整个 ZooKeeper 才依然可用。假如我们的集群中有 n 台 ZooKeeper 服务器,那么也就是剩下的服务数必须大于 n/2。先说一下结论,2n 和 2n-1 的容忍度是一样的,都是 n-1,大家可以先自己仔细想一想,这应该是一个很简单的数学问题了。 比如假如我们有 3 台,那么最大允许宕掉 1 台 ZooKeeper 服务器,如果我们有 4 台的的时候也同样只允许宕掉 1 台。 假如我们有 5 台,那么最大允许宕掉 2 台 ZooKeeper 服务器,如果我们有 6 台的的时候也同样只允许宕掉 2 台。

综上,何必增加那一个不必要的 ZooKeeper 呢?

Licensed under CC BY-NC-SA 4.0
最后更新于 May 23, 2022 21:18 CST
Built with Hugo
主题 StackJimmy 设计