搞懂 ZooKeeper 集群的数据同步 (2)

另一种情况是如果 Follower 的 zxid 不在 min 和 max 的区间内时,但当 zookeeper.snapshotSizeFactor 配置大于 0 的话(默认是 0.33),会尝试使用 log 进行 DIFF,但是需要同步的 log 文件的总大小不能超过当前最新的 snapshot 文件大小的三分之一(以默认 0.33 为例)的话,才可以通过读取 log 文件中的写请求记录进行 DIFF 同步。同步的方法也和上面一样,先发送一个 DIFF 给 Follower 然后从 log 文件中找到该 Follower 的区间,再一条条的发送 PROPOSAL 和 COMMIT。

而 Follower 收到 PROPOSAL 的暗号消息后,就会像处理客户端请求那样去一条条处理,慢慢就会将数据恢复成和 Leader 是一致的。

1.2 SNAP

假设现在三个办事处是这样的

搞懂 ZooKeeper 集群的数据同步

马果果的写请求队列在默认配置下记录了 277 至 777 的写请求,又假设现在的场景不满足上面 1.1.2 的情况,马果果就知道当前需要通过 SNAP 的情况进行同步了。

马果果会先发送一个 SNAP 的请求给马小云马小腾让他们准备起来

搞懂 ZooKeeper 集群的数据同步

紧接着就会当前内存中的数据整个序列化(和 snapshot 文件是一样的)然后一起发送给马小云马小腾

马小云马小腾收到马果果发来的整个 snapshot 之后会先清空自己当前的数据库的所有信息,接着直接将收到的 snapshot 反序列化就完成了整个内存数据的恢复。

1.3 TRUNC

最后一种策略的场景假设是这样:

搞懂 ZooKeeper 集群的数据同步

假设马小腾是上一个 Leader,但是经历了停电以后恢复重新以 Follower 的身份加入集群,但是他的 zxid 要比 max 还大,这个时候马果果就会给马小腾发送 TRUNC,(至于图中为什么马小云不举例为 TRUNC,因为如果马小云的 zxid 也比马果果要大的话,马果果在当前场景下就不可能当选 Leader 了)。

马果果就会发送 TRUNC 给马小腾(这里忽略马小云

搞懂 ZooKeeper 集群的数据同步

假设马小腾的本地 log 文件目录下是这样的:

/tmp └── zookeeper └── log └── version-2 └── log.0 └── log.500 └── log.800

马小腾收到 TRUNC 之后,会找到本地 log 文件中所有大于 777 的 log 文件删除,即这里的 log.800 ,然后会在 log.500 这个文件找到 777 这个 zxid 记录并且把当前文件的读写指针修改至 777 的位置,之后针对该文件的读写操作就会从 777 开始,这样就会把之后的那些记录给覆盖了。

马果果这边当判断完同步策略并发送给另外两马之后,便会发送一个 NEWLEADER 的信息给他们

搞懂 ZooKeeper 集群的数据同步

马小云马小腾在收到 NEWLEADER 之后,若之前是通过 SNAP 方式同步数据的话,这里会强制快照一份新的 snapshot 文件在自己这里。然后会回复给马果果一个 ACK 的消息,告诉他自己的同步数据已经完成了

搞懂 ZooKeeper 集群的数据同步

然后马果果同样会等待半数一样的 ACK 接收完成后,再发送一个 UPTODATE 给其他两马,告诉他们现在办事处数据已经都一致了,可以开始对外提供服务了

搞懂 ZooKeeper 集群的数据同步

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpwsgx.html