Zookeeper服务端初始化过程(三):数据恢复与同步
server类型(ServerType)
|
client端服务类
|
server端服务类
|
Leader(new)
|
LeaderZookeeperServer
|
Leader
|
Follower
|
FollowerZookeeperServer
|
FolloweràLearner
|
Observer
|
ObserverZookeeperServer
|
ObserveràLearner
|
- 在选举中,即当server的状态为LOOKING是,将会实例化一个ReadOnlyZookeeperServer来临时为client服务(如果server开启了readonly模式)。
- Leader是否可以直接服务于Client,取决于配置文件中“zookeeper.leaderServes”参数,即leader是否支持client服务.(当Leader不支持时,似乎是以异常的方式结束client链接,导致client被强制和其他Follower链接)。
- Client与server之间是通过NIO方式(长连接)进行通信,server端为单线程处理;每个socket链接对于server端而言,都有一个ServerCnxn类来维护,所有的请求ServerCnxnFatory之后交付给相应的ServerCnxn,最终请求packet经过zookeeperServer实例的各个processor处理。(“请求”全序性)
- Follower与Leader之间的通信,有些不同;Leader会维护每个Follower之间的链接,当然也是长连接,不过并没有使用NIO,而是普通的socket通信(同步数据交互,而非异步);Leader会为每个链接的Follower/Observer创建一个LearnerHandler线程,用于处理2者之间的数据交互,LearnerHandler类持有Leader实例;所以对于Leader而言,是多线程处理Follower/Observer的数据交互。
- LearnerCnxAcceptor,一个非常简单的线程,为Leader的内部类。它的主要作用是accept来自Follower/Observer的链接(侦听followingPort),为每个socket绑定一个LearnerHandler处理器线程,此线程持有socket句柄。此线程处理来自Follower/Observer的请求,并发送Leader的请求给Follower/Observer.
- 选举之前epoch来自server当前的zxid,N轮选举成功之后,最终的最大的epoch将作为最终的epoch;zxid的前32位为epoch,所以每次选举之后,leader的职责就是重新计算zxid,以免发生重复;在lead正式服务之前,这个重置的zxid(或者说是epoch)尚不能作为真正的zxid,即还不能持久在db中。此zxid经过大多数的Follower赞同之后(赞同:即所有现存的Follower都没有比此epoch更大的)才可以使用,在新leader提议这个epoch时,如果发现>=当前epoch时,leader就将较大的epoch +1并赋值给当前epoch,以确保新leader在服务器之前,所采用的epoch为最大的。(参见:Leader.getEpochToPropose())Epoch提议只会被计算一次,并且多数派时(包括leader在内),此epoch才能被生效,并参与接下来新的zxid生成。
-
Leader.getEpochToPropose(sid,lastAcceptedEpoch),这个方法会在leader.lead()和LearnerHandler中调用,此方法会阻塞,直到leader提交自己的epoch,并且“大多数”Follower也提交(LearnerHandler中)。所以在上述2个方法中,均会像”栅栏”一样,阻塞每个peer的执行此方法比较leader.epoch和每个sid所交付的lastAcceptedEpoch,并确保leader.epoch是最大的(且不相等,相等时,会+1):
if (lastAcceptedEpoch >= epoch) {
epoch = lastAcceptedEpoch+1;
}
Leader.lead()即表示leader提交自己的epoch.;LearnerHandler线程时负责接受follower连接的,所以在每个follower建立连接时也会向leader首先交付自己的epoch.只有在epoch达成一致之后,才能进行实际的通讯.
- 经过3)之后,leader和follower确认了epoch(选举票根)之后,leader计算并db持久化zxid,同是将自己(leader)目前的(epoch,zxid)信息封装,在此同时各个参与选举的follower也做同样的操作,不过每个follower所交付的zxid可能不同,但是他们不能比当前leader更”超前”(如果超前,将抛出异常,系统认为leader职能失败,重新选举),各个follower陆续向leader确认(epoch,zxid),如果此时大部分参与选举的follower都参与了确认且正常,那么到此为止,leader和follower各自的角色被真正决定,同时follower和leader之间的zxid步差也将被计算出来.[follower的ack操作也是在LearnerHandler中进行,3]操作之后]
- 此期间有个小小的细节,leader在和follower确认epoch和zxid时,会创建一个”标记”性proposal,此提议的zxid为根据epoch新计算的其中counter(计数器位)为0,在learnerHandler.run中,所有的follower都同步完毕,并手动去提交ACK消息时(leader.processAck),当所有的follower都ACK之后,将会导致LeaderZookeeperServer启动,接下来leader就可以为client提供服务了.
- 其实代码的复杂度还是很大.在LearnerHandler.run()和Follower.followLeader()方法中存在顺序性的交互操作.那么Leader.lead()只是根据上述2个方法的交互作为状态判断(有同步的过程).
- 当leader和follower确认”角色”关系之后,每个follower所对应的LearnerHandler就可以从follower发送的packet中得到当前follower所持有的最大的zxid,通过此zxid和leader所持有commitedLog中最大的czxid比较,如果follower的zxid比较大,那么handler将会首先发送一个TRUNC信号,让follower清除czxid之后的所有记录;如果follower的zxid比较小,那么此时handler将会遍历commitedLog,将zxid之后的所有记录,封装成”提议”直接发送给follower(此提议为commit状态,即follower直接提交,不再ACK),当数据同步完毕之后,handler最后向follower交付一个UPTODATE的标记提议,告知follower,数据已经同步结束,它即可开始为client服务了.
- LearnerHandler向follower同步完数据之后,即进入while自选循环中,用于顺序接收follower所发送的各种类型的提议,并做不同的业务处理.那么同时Follower也进入了服务状态(while循环),接收client的请求,响应事件,转发write操作等.
- 大小: 44.8 KB
- 大小: 77.6 KB
分享到:
相关推荐
apache-zookeeper-3.7.1 apache-zookeeper-3.7.1 apache-zookeeper-3.7.1 apache-zookeeper-3.7.1 apache-zookeeper-3.7.1 apache-zookeeper-3.7.1 apache-zookeeper-3.7.1 apache-zookeeper-3.7.1 apache-zookeeper...
zookeeper-3.4.14,包含添加系统服务插件及添加bat. 1. zookeeper-3.4.14源包 2. commons-daemon-1.1.0-bin-windows.zip 插件 3. 配置好插件的zookeeper-3.4.14包,右键管理员权限执行zk-server-install.bat
apache-zookeeper-3.6.0.tar.gz
zookeeper-3.4.9.tar.gz
apache-zookeeper-3.5.7-bin.tar.gz 。
zookeeper-3.4.8zookeeper-3.4.8zookeeper-3.4.8zookeeper-3.4.8
zookeeper-3.4.5-cdh5.16.2.tar.gz 资源包,之前的原网站上无法下载,后经多种途径下载到该资源包,上传到博客上供大家使用。
zookeeper-3.4.6 解压后可直接运行 bin/zkServer.cmd 来启动
赠送jar包:zookeeper-3.4.10.jar; 赠送原API文档:zookeeper-3.4.10-javadoc.jar; 赠送源代码:zookeeper-3.4.10-sources.jar; 赠送Maven依赖信息文件:zookeeper-3.4.10.pom; 包含翻译后的API文档:zookeeper-...
ZooKeeper是一个分布式的,开放源码的分布式应用程序协调...ZooKeeper代码版本中,提供了分布式独享锁、选举、队列的接口,代码在zookeeper-3.4.3\src\recipes。其中分布锁和队列有Java和C两个版本,选举只有Java版本。
zookeeper-3.4.8.jar
赠送jar包:zookeeper-3.3.3.jar; 赠送原API文档:zookeeper-3.3.3-javadoc.jar; 赠送源代码:zookeeper-3.3.3-sources.jar; 包含翻译后的API文档:zookeeper-3.3.3-javadoc-API文档-中文(简体)版.zip 对应...
放在压缩包里了, 在windows下解压出"zookeeper-3.4.14.tar.gz"之后上传至虚拟机即可
apache-zookeeper分布式框架,压缩包内容:(apache-zookeeper-3.7.1-bin.tar.gz、apache-zookeeper-3.7.1.tar.gz、apache-zookeeper-3.6.4-bin.tar.gz、apache-zookeeper-3.6.4.tar.gz、apache-zookeeper-3.5.10-...
zookeeper-3.4.5.jar; zookeeper-3.4.5.jar; zookeeper-3.4.5.jar;
最新版linux apache-zookeeper-3.7.0-bin.tar.gz最新版linux apache-zookeeper-3.7.0-bin.tar.gz
zookeeper-3.4.10和zookeeper-3.4.12
apache-zookeeper-3.7.0-bin.tar.gz
apache-zookeeper-3.5.5.tar.gz,zookeeper的安装文件,解压后配置集群即可
apache-zookeeper-3.5.10-bin 环境搭配 ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,...