Zookeeper:基础
架构(Architecture)
- Leader: ZooKeeper 集群工作的核心。
- 事务请求(写操作)的唯一调度和处理者,保证集群事务处理的顺序性;集群内部各个服务的调度者。
- 对于 create,setData,delete 等有写操作的请求,则需要统一转发给 leader 处理,leader 需要决定编号、执行操作,这个过程称为一个事务。
- Follower: 处理客户端非事务(读操作)请求。
- 转发事务请求给 Leader;
- 参与集群;
- leader 选举投票 2n-1 台可以做集群投票。
- Observer: 观察者角色。
- 观察 ZooKeeper 集群的最新状态变化并将这些状态同步过来,其对于非事务请求可以进行独立处理,对于事务请求,则会转发给Leader服务器处理。
- 不会参与任何形式的投票只提供服务,通常用于在不影响集群事务处理能力的前提下提升集群的非事务处理能力。
Leader 选举
Leader 选举是保证分布式数据一致性的关键所在。
Leader 选举分为 Zookeeper 集群初始化启动时选举和 Zookeeper 集群运行期间重新选举两种情况。
- 若进行 Leader 选举,则至少需要两台机器,这里选取 3 台机器组成的服务器集群为例。
选举过程中的相关参数:
- 服务器ID(myid):在选举算法中,编号越大权重越大。
- 事务ID(zxid):在选举算法中,值越大权重越大(说明数据越新)。
- ZooKeeper 状态的每次变化都接收一个 ZXID(ZooKeeper 事务 id)形式的标记。
- ZXID 是一个 64 位的数字,由 Leader 统一分配,全局唯一,不断递增。
- ZXID 展示了所有的 ZooKeeper 的变更顺序。(如果 zxid1 小于 zxid2 说明 zxid1 在 zxid2 之前发生)
- 逻辑时钟(epoch-logicalclock):在选举算法中,同一轮投票过程中的逻辑时钟值是相同的,每投完一次值会增加。
选举过程中的节点状态:
- LOOKING:寻找 Leader 状态,处于该状态需要进入选举流程;
- LEADING:领导者状态,处于该状态的节点说明是角色已经是 Leader;
- FOLLOWING:跟随者状态,表示 Leader 已经选举出来,当前节点角色是 follower;
- OBSERVER:观察者状态,表明当前节点角色是 observer;
- OBSERVING 不参与投票。
初始化启动时选举
在集群初始化阶段,当有一台服务器 ZK1 启动时,其单独无法进行和完成 Leader 选举,当第二台服务器 ZK2 启动时,此时两台机器可以相互通信,每台机器都试图找到 Leader,于是进入 Leader 选举过程。
选举流程如下图:
节点的选举操作流程:
选举过程如下:
- 发出投票:每个Server发出一个投票。
- 由于是初始情况,ZK1 和 ZK2 都会将自己作为 Leader 服务器来进行投票,每次投票会包含所推举的服务器的 myid 和 ZXID,使用(myid, ZXID)来表示,此时 ZK1 的投票为(1, 0),ZK2 的投票为(2, 0),然后各自将这个投票发给集群中其他机器。
- 接受投票:接受来自各个服务器的投票。
- 集群的每个服务器收到投票后,首先判断该投票的有效性,如检查是否是本轮投票(根据 epoch-logicalclock)、是否来自 LOOKING 状态的服务器。
- 处理投票:针对每一个投票,服务器都需要将别人的投票和自己的投票进行比较。
- 规则如下:
- 检查 epoch;
- 先比较 zxid:zxid 比较大的服务器优先作为 Leader。
- 再比较 myid:如果 zxid 相同,myid 较大的服务器作为Leader服务器。
- 对于 ZK1 而言,它的投票是(1, 0),接收 ZK2 的投票为(2, 0),首先会比较两者的 ZXID,均为 0,再比较 myid,此时 ZK2 的 myid 最大,于是 ZK2 胜。ZK1 更新自己的投票为(2, 0),并将投票重新发送给 ZK2。
- 规则如下:
- 统计投票:每次投票后,服务器都会统计投票信息,判断是否已经有过半机器接受到相同的投票信息。
- 对于 ZK1、ZK2 而言,都统计出集群中已经有两台机器接受了(2, 0)的投票信息,此时便认为已经选出 ZK2 作为Leader。
- 改变服务器状态:一旦确定了 Leader,每个服务器就会更新自己的状态:如果是 Follower,那么就变更为 FOLLOWING,如果是 Leader,就变更为 LEADING。
- 当新的 Zookeeper 节点 ZK3 启动时,发现已经有 Leader 了,不再选举,直接将直接的状态从 LOOKING 改为 FOLLOWING。
运行期间重新选举
在 Zookeeper 运行期间,如果 Leader 节点挂了,那么整个 Zookeeper 集群将暂停对外服务,进入新一轮Leader选举。
选举流程如下图:
选举过程如下:
- 变更状态:Leader 挂后,余下的非 Observer 服务器都会讲自己的服务器状态变更为 LOOKING,然后开始进入 Leader 选举过程。
- 发出投票:每个Server会发出一个投票。
- 在运行期间,每个服务器上的 ZXID 可能不同,此时假定 ZK1 的 ZXID 为 124,ZK3 的 ZXID 为 123;在第一轮投票中,ZK1 和 ZK3 都会投自己,产生投票(1, 124),(3, 123),然后各自将投票发送给集群中所有机器。
- 接受投票:(同“初始化启动时选举”)
- 处理投票:(同“初始化启动时选举”)
- 由于 ZK1 事务 ID 大,ZK1 将会成为 Leader。
- 统计投票:(同“初始化启动时选举”)
- 改变服务器的状态:(同“初始化启动时选举”)