网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
数据的初始化从磁盘中加载数据的过程,主要包括了从快照文件中加载快照数据和根据事务日志进行数据订正两个过程。
1. 初始化FileTxnSnapLog
FileTxnSnapLog是Zookeeper事务日志和快照数据访问层,用于衔接上层业务与底层数据存储,底层数据包含了事务日志和快照数据两部分,因此FileTxnSnapLog内部又分为FileTxnLog和FileSnap的初始化,分别代表事务日志管理器和快照数据管理器的初始化。
2. 初始化ZKDatabase
完成FileTxnSnapLog的初始化后,就要开始构建内存数据库ZKDatabase了,在初始化过程中,首先会构建一个初始化DataTree,同时会将步骤1中初始化的FileTxnSnapLog交给ZKDatabase,以便内存数据库能够对事务日志和快照数据进行访问。
3. 创建PlayBackListener监听器
PlayBackListener监听器主要用来接收事务应用过程中的回调,在Zookeeper数据恢复后期,会有一个事务订正的过程,在这个过程中,会回调PlayBackListener监听器来进行对应的数据订正。PlayBackListener会将这些刚刚应用到内存数据库中的事务转存到ZKDatabase.committedLog中,以便集群中服务器间进行快速的数据同步。
4. 处理快照文件
完成内存数据库的初始化后,java培训Zookeeper就可以开始从磁盘中恢复数据了,每一个快照数据文件中都保存了Zookeeper服务器几乎全量的数据,因此首先会从这些快照文件开始加载。
5. 获取最新的100个快照文件
Zookeeper会加载最新的至多100个快照文件。
6. 解析快照文件
如果正确性校验通过的话,那么通常只会解析最新的那个快照文件。只有当最新的快照文件不可用时,才会逐个解析,直到将这100个文件全部解析完。
7. 获取最新的ZXID
完成步骤6后,就已经基于快照文件构建了一个完整的DataTree实例和sessionsWithTimeouts集合汇总,此时根据这个快照文件的文件名就可以解析出一个最新的ZXID:zxid_for_snap,代表了Zookeeper开始进行数据快照的时刻。
8. 处理事务日志
经过前面7步流程的处理,此时Zookeeper服务器内存中已经有了一份近似全量的数据了,现在开始就要通过事务日志来更新增量数据了。
9. 获取所有zxid_for_snap之后提交的事务
Zookeeper中数据的快照机制决定了快照文件中并非包含了所有的事务操作,但是未被包含在快照文件中的那部分事务操作可以通过数据订正来实现,因此,我们这里只需要从事务日志中获取所有ZXID比步骤7得到的zxid_for_snap大的事务操作即可。
10. 事务应用
获取到所有ZXID大于zxid_for_snap的事务后,将其逐个应用到之前基于快照文件恢复出来的
DataTree和sessionsWithTimeouts中。
每当有一个事务被应用到内存数据库汇总,Zookeeper同时会回调PlayBackListener监听器,将这一事务操作记录转换成Proposal,并保存到ZKDatabase.committedLog中,以便Follower进行快速同步。
11. 获取最新ZXID
待所有的事务都被完整地应用到内存数据库中之后,基本上也就完成了数据的初始化过程,此时再获取一个ZXID,用来表示上次服务器正常运行时提交的最大事务ID。
12. 校验epoch
每次选举产生一个新的Leader服务器之后,就会生成一个新的epoch,在完成数据加载后,Zookeeper从步骤11中确定的ZXID中解析出事务处理的Leader周期,同时也会从磁盘文件中读取出上次记录的最新epoch值,进行校验。
接下来,我们就来看看数据同步的流程是怎样的。
二、数据同步
在介绍数据同步流程中,我们使用Learner代表所有非Leader服务器。
在集群服务器启动过程中,当整个集群完成Leader选举之后,Learner服务器会向Leader服务器进行注册,当所有服务器都注册完之后,就进入到了数据同步环节。数据同步过程就是Leader服务器将那些没有在Learner服务器上提交过的事务请求同步给Learner服务器。
大体过程如下:
获取Learner状态
在注册Learner的最后阶段,Learner服务器会发送给Leader服务器一个ACKEPOCH数据包,Leader会从这个数据包中解析出该LearnerDE currentEpoch和lastZxid。
数据同步初始化
在开始数据同步之前,Leader服务器会进行数据同步初始化,首先会从Zookeeper的内存数据库中提取出事务请求对应的提议缓存队列proposals,同时完成以下三个ZXID值的初始化:
- peerLastZxid:该Learner服务器最后处理的ZXID
- minCommittedLog:Leader服务器提议缓存队列committedLog中的最小ZXID
- maxCommittedLog:Leader服务器提议缓存队列committedLog中的最大ZXID
Zookeeper集群数据同步分四类:直接差异化同步(DIFF同步)、先回滚再差异化同步(TRUNC+DIFF同步)、仅回滚同步(TRUNC同步)和全量同步(SNAP同步)。java培训在初始化节点,Leader服务器会优先初始化以全量同步方式来同步数据,但不是最终的同步方式,最终的同步方式会根据Leader和Learner服务器之间的数据差异情况来决定。
直接差异化同步(DIFF同步)
场景:peerLastZxid介于minCommittedLog和maxCommittedLog之间。
对于这种场景,直接使用直接差异化同步方式即可。Leader服务器会首先向这个Learner发送一个DIFF指令,用于通知Learner进入差异化数据同步阶段。在实际Proposal同步过程中,针对每个Proposal,Leader服务器都会通过发送两个数据包来完成,分别是PROPOSAL内容数据包和COMMIT指令数据包。
举例说明:假如某个时刻Leader服务器的提议缓存队列对应的ZXID依次是:
0x500000001、0x500000002、0x500000003、0x500000004、0x500000005
而Learner服务器最后处理的ZXID为0x500000003,于是Leader服务器就会依次将0x500000004和0x500000005两个提议同步给Learner服务器,同步过程中的数据包发送顺序如下:
发送顺序 | 数据包类型 | 对应的ZXID |
1 | PROPOSAL | 0x500000004 |
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
,可以戳这里获取](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)**
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!