写入数据流程
请求发给Leader
-
client向Zookeeper集群的Leader节点发送写请求
-
Leader节点接收到写请求后,会对请求进行预处理,并为这次写操作分配一个全局唯一的递增ID(ZXID)。
-
Leader将这个写请求(提案)广播给所有的Follower节点。这个提案包含了请求的具体内容和分配的ZXID。每个Follower节点在接收到提案后,会将其写入到本地的事务日志中,并向Leader回应一个投票(acknowledgment),表示它已经准备好这次更改。
-
当Leader收到半数以上的Follower的成功信息,说明写操作可以执行,然后,Leader会向所有Follower节点广播一个提交消息,指示它们可以将这个写操作应用到自己的状态机中了。Follower节点收到提交消息后,会将之前写入事务日志的提案应用到自己的状态机中,完成数据的更改。
-
一旦写操作被成功应用,Leader会向发起请求的客户端发送响应,告知写操作已经完成。
-
注意: 此时写操作只是在超过一半的机器中完成了,但是客户端会认为整个写操作都成功了,之后Leader会将没有同步的follower节点数据进行同步.
请求发给Follower
-
Follower节点接收到客户端的写请求后,并不会直接处理这个请求。
-
Follower会将这个请求转发给Leader节点。
-
Leader节点接收到这个写请求后,会对请求进行预处理。这包括为写操作分配一个全局唯一的递增ID(ZXID),然后,Leader将这个写请求(提案)广播给所有的Follower节点,包括最初接收到请求的Follower。这个广播包含了请求的细节和分配的ZXID。
-
每个Follower节点在接收到提案后,会将其写入到本地的事务日志中。然后,Follower节点会向Leader发送一个投票(acknowledgment),表示它已经准备好这次更改。
-
当Leader收到半数以上的Follower的成功信息,说明写操作可以执行,然后,Leader会向所有Follower节点广播一个提交消息,指示它们可以将这个写操作应用到自己的状态机中了。Follower节点收到提交消息后,会将之前写入事务日志的提案应用到自己的状态机中,完成数据的更改。
-
一旦写操作被成功应用,接收请求的follower会向发起请求的客户端发送响应,告知写操作已经完成。
Zookeeper的崩溃恢复机制
已经被处理的消息不能丢失
1,当 Leader 收到超过半数 Follower 的 ACKs 后,就向各个 Follower 广播 COMMIT 消息, 批准各个 Follower 执行该写操作事务。
2,各个 Follower 在接收到 Leader 的 COMMIT 消息后就会在本地执行该写操作,然后会向客户端响应写操作成功。
3,但是如果在非全部 Follower 收到 COMMIT 消息之前 Leader 就挂了,这将导致一种后 果:部分 Follower 已经执行了该事务,而部分 Follower 尚未收到 COMMIT 消息,所以其并没有执行该事务。
4,当新的 Leader 被选举出,集群经过恢复模式后需要保证所有 Follower 上都执行 了那些已经被部分 Follower 执行过的事务。
被丢弃的消息不能再出现
1,新事务在 Leader 上已经通过,其已经将该事务更新到了本地,但所有 Follower 还都没有收到 COMMIT 之前,Leader 宕机了(比前面叙述的宕机更早)
2,此时,所有 Follower 根本 就不知道该 Proposal 的存在。当新的 Leader 选举出来,整个集群进入正常服务状态后,之 前挂了的 Leader 主机重新启动并注册成为了 Follower。
3,那个别人根本不知道的 Proposal 还保留在那个主机,那么其数据就会比其它主机多出了内容,导致整个系统状态的不一致。所以,该 Proposa 应该被丢弃。
4,类似这样应该被丢弃的事务,是不能再次出现在集群中的, 应该被清除。
标签:事务,同步,请求,Zookeeper,Leader,Follower,理解,操作,节点 From: https://blog.csdn.net/m0_63130425/article/details/139183388