1:先投自己,广播出去。
2:收到他人投票,与自己的投票pk,改变投票,广播出去,然后统计投票结果。
3: 出现超过一半的投票,选出master,改变状态。master/follwing。
4:master发送心跳,同步数据,数据同步完后提供服务。
事务日志 :用于存放事务执行的相关信息,如zxid、cxid等。采用mappedFile,会文件预热,异步刷盘。
快照日志:zookeeper数据节点数据是运行在内存中的,当然内存保存这些结点的数据不可能无限大,而且数据节点的内容是动态变化的,因此zookeeper提供将数据节点持久化的机制,每隔一段时间,zookeeper会将内存中的数据节点DataTree序列到磁盘中,因此就形成了我们的快照日志。
ZooKeeper使用事务日志和快照来持久化每个事务(注意是事务日志先写)。该配置项指定ZooKeeper在将内存数据库序列化为快照之前,需要先写多少次事务日志。也就是说,每写几次事务日志,就快照一次。默认值为100000。为了防止所有的ZooKeeper服务器节点同时生成快照(一般情况下,所有实例的配置文件是完全相同的),当某节点的先写事务数量在(snapCount/2+1,snapCount)范围内时(挑选一个随机值),这个值就是该节点拍快照的时机。
数据恢复:数据恢复时,会加载最近100个快照文件(如果没有100个,就加载全部的快照文件)。之所以要加载100个,是因为防止最近的那个快照文件不能通过校验。在逐个解析过程中,如果正确性校验通过之后,那么通常就只会解析最新的那个快照文件,但是如果校验发现最先的那个快照文件不可用,那么就会逐个进行解析。当基于快照文件构建了一个完整的DataTree实例和sessionWithTimeouts集合后,此时根据这个快照文件的文件名就可以解析出最新的ZXID,该ZXID代表了zookeeper开始进行数据快照的时刻,然后利用此ZXID定位到具体事务文件从哪一个开始,然后执行事务日志对应的事务,恢复到最新的状态,并得到最新的ZXID。
数据的同步都是由leader发起,简单来说,learner启动时都会向leader建立连接,由leader分别对followe和observer进行数据同步,有全量同步、仅回滚同步、先回滚再差异化同步、直接差异化同步四种同步指令。
leader发送给learner的差异化数据同步指令(proposal),如果learner同意就会返回ack,如果leader收到ack,就会同时进入过半策略的等待阶段—leader会和其他learner服务器进行上述同样的数据同步流程,知道集群中有过半的learner机器响应了leader的这个ack消息。
一旦满足过半策略后,leader服务器就会向所有已经完成数据同步的learner机器发送一个uptodate指令,用来通知learner已经完成了数据同步,同时集群中已经有过半机器完成了数据同步,集群已经具备了对外服务的能力了。
learner在接收到这个uptodate指令后,向leader再反馈一个ack消息。
如果集群中的follewer接收到来自客户端的写请求,follower会将消息通过REQUEST请求给到leader,统一交给leader来处理,leader处理结束之后,会再次广播数据。读请求就自己处理。
【zookeeper面试】最终一致性?
分布式锁?
推荐阅读
- 面试官(HTTPS 是如何保证传输安全的(你必须学会。。。))
- GC垃圾回收的原理和涉及的几种算法
- java小贴士|面试官问(什么是浅拷贝和深拷贝())
- 面试|面试题-深拷贝和浅拷贝区别是什么()
- Java基础的查漏补缺|Java基础查漏补缺之你可能不知道的final关键字的知识点
- Spring|ssm框架整合
- Java聊天机器人的简单实现
- Java基础总结|Java期末复习速成(七)
- Java基础总结|Java期末复习速成(六)