集群

予早 2025-10-09 21:13:59
Categories: Tags:

zookeeper 选举机制

1)服务器1启动,发起一次选举。服务器1投自己一票。此时服务器1票数一票,不够半数以上(3票),选举无法完成,服务器1状态保持为LOOKING;
2)服务器2启动,再发起一次选举。服务器1和2分别投自己一票并交换选票信息:此时服务器1发现服务器2的myid比自己目前投票推举的(服务器1)大,更改选票为推举服务器2。此时服务器1票数0票,服务器2票数2票,没有半数以上结果,选举无法完成,服务器1,2状态保持LOOKING。
3)服务器3启动,发起一次选举。此时服务器1和2都会更改选票为服务器3。此次投票结果:服务器1为0票,服务器2为0票,服务器3为3票。此时服务器3的票数已经超过半数,服务器3当选Leader。服务器1,2更改状态为FOLLOWING,服务器3更改状态为LEADING;
4)服务器4启动,发起一次选举。此时服务器1,2,3已经不是LOOKING状态,不会更改选票信息。交换选票信息结果:服务器3为3票,服务器4为1票。此时服务器4服从多数,更改选票信息为服务器3,并更改状态为FOLLOWING;
5)服务器5启动,同4一样当小弟。
————————————————
版权声明:本文为CSDN博主「ha_lydms」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/lydms/article/details/132921358

Zookeeper集群主要角色有Server和client,其中,Server又分为Leader、Follower和Observer三个角色,每个角色的含义如下:

Zookeeper集群中每个Server在内存中存储了一份数据,在Zookeeper启动时,将从实例中选举一个Server作为Leader,Leader负责处理数据更新等操作,当且仅当大多数Server在内存中成功修改数据,才认为数据修改成功。

Zookeeper写的流程为:客户端Client首先和一个Server或者Observer通信,发起写请求,然后Server将写请求转发给Leader,Leader再将写请求转发给其它Server,其它Server在接收到写请求后写入数据并响应Leader,Leader在接收到大多数写成功回应后,认为数据写成功,最后响应Client,完成一次写操作过程。

2.4. 集群角色

Zookeeper 集群是一个基于主从复制的高可用集群,集群中每个节点都存储了一份数据副本(内存中)。此外,每个服务器节点承担如下三种角色中的一种:

客户端可以从任意 ZooKeeper 服务器节点读取数据,但只能通过 Leader 服务写数据并需要半数以上 Follower 的 ACK,才算写入成功。记住这个重要的知识点,下文会详细讲述。

会话

ZooKeeper 客户端通过 TCP 长连接连接到 ZooKeeper 服务集群会话 (Session) 从第一次连接开始就已经建立,之后通过心跳检测机制来保持有效的会话状态

每个 ZooKeeper 客户端配置中都配置了 ZooKeeper 服务器集群列表。启动时,客户端会遍历列表去尝试建立连接。如果失败,它会尝试连接下一个服务器,依次类推。

一旦一台客户端与一台服务器建立连接,这台服务器会为这个客户端创建一个新的会话。每个会话都会有一个超时时间,若服务器在超时时间内没有收到任何请求,则相应会话被视为过期。一旦会话过期,就无法再重新打开,且任何与该会话相关的临时 znode 都会被删除。

通常来说,会话应该长期存在,而这需要由客户端来保证。客户端可以通过心跳方式(ping)来保持会话不过期。

事务

对于来自客户端的每个更新请求,ZooKeeper 具备严格的顺序访问控制能力。

为了保证事务的顺序一致性,ZooKeeper 采用了递增的事务 id 号(zxid)来标识事务

Leader 服务会为每一个 Follower 服务器分配一个单独的队列,然后将事务 Proposal 依次放入队列中,并根据 FIFO(先进先出) 的策略进行消息发送。Follower 服务在接收到 Proposal 后,会将其以事务日志的形式写入本地磁盘中,并在写入成功后反馈给 Leader 一个 Ack 响应。当 Leader 接收到超过半数 Follower 的 Ack 响应后,就会广播一个 Commit 消息给所有的 Follower 以通知其进行事务提交,之后 Leader 自身也会完成对事务的提交。而每一个 Follower 则在接收到 Commit 消息后,完成事务的提交。

所有的提议(**proposal**)都在被提出的时候加上了 zxid。zxid 是一个 64 位的数字,它的高 32 位是 epoch 用来标识 Leader 关系是否改变,每次一个 Leader 被选出来,它都会有一个新的 epoch,标识当前属于那个 leader 的统治时期。低 32 位用于递增计数。

详细过程如下:

  1. Leader 等待 Server 连接;
  2. Follower 连接 Leader,将最大的 zxid 发送给 Leader;
  3. Leader 根据 Follower 的 zxid 确定同步点;
  4. 完成同步后通知 follower 已经成为 uptodate 状态;
  5. Follower 收到 uptodate 消息后,又可以重新接受 client 的请求进行服务了

3.1. 读操作

Leader/Follower/Observer 都可直接处理读请求,从本地内存中读取数据并返回给客户端即可

由于处理读请求不需要服务器之间的交互,Follower/Observer 越多,整体系统的读请求吞吐量越大,也即读性能越好。

所有的写请求实际上都要交给 Leader 处理。Leader 将写请求以事务形式发给所有 Follower 并等待 ACK,一旦收到半数以上 Follower 的 ACK,即认为写操作成功。

#写 Leader

由上图可见,通过 Leader 进行写操作,主要分为五步:

  1. 客户端向 Leader 发起写请求
  2. Leader 将写请求以事务 Proposal 的形式发给所有 Follower 并等待 ACK
  3. Follower 收到 Leader 的事务 Proposal 后返回 ACK
  4. Leader 得到过半数的 ACK(Leader 对自己默认有一个 ACK)后向所有的 Follower 和 Observer 发送 Commmit
  5. Leader 将处理结果返回给客户端

写 Follower/Observer

观察

ZooKeeper 允许客户端监听它关心的 znode,当 znode 状态发生变化(数据变化、子节点增减变化)时,ZooKeeper 服务会通知客户端

ZAB

Zookeeper Atomic Broadcast,ZooKeeper 原子广播

https://dunwu.github.io/bigdata-tutorial/zookeeper/ZooKeeper%E5%8E%9F%E7%90%86.html#_4-zab-%E5%8D%8F%E8%AE%AE