Zookeeper 源码分析-启动
本文主要介绍了zookeeper启动的过程
运行zkServer.sh start命令可以启动zookeeper。入口的main函数在类中QuorumPeerMain。
main函数主要调用了runFromConfig函数,创建了QuorumPeer对象,并且调用了start函数,从而启动了zookeeper。
- public class QuorumPeerMain {
- protected QuorumPeer quorumPeer;
- /**
- * To start the replicated server specify the configuration file name on
- * the command line.
- * @param args path to the configfile
- */
- public static void main(String[] args) {
- QuorumPeerMain main = new QuorumPeerMain();
- main.initializeAndRun(args);
- }
- protected void initializeAndRun(String[] args)
- throws ConfigException, IOException
- {
- runFromConfig(config);
- }
- public void runFromConfig(QuorumPeerConfig config) throws IOException {
- LOG.info("Starting quorum peer");
- try {
- NIOServerCnxn.Factory cnxnFactory =
- new NIOServerCnxn.Factory(config.getClientPortAddress(),
- config.getMaxClientCnxns());
- quorumPeer = new QuorumPeer();
- quorumPeer.setClientPortAddress(config.getClientPortAddress());
- quorumPeer.setTxnFactory(new FileTxnSnapLog(
- new File(config.getDataLogDir()),
- new File(config.getDataDir())));
- quorumPeer.setQuorumPeers(config.getServers());
- quorumPeer.setElectionType(config.getElectionAlg());
- quorumPeer.setMyid(config.getServerId());
- quorumPeer.setTickTime(config.getTickTime());
- quorumPeer.setMinSessionTimeout(config.getMinSessionTimeout());
- quorumPeer.setMaxSessionTimeout(config.getMaxSessionTimeout());
- quorumPeer.setInitLimit(config.getInitLimit());
- quorumPeer.setSyncLimit(config.getSyncLimit());
- quorumPeer.setQuorumVerifier(config.getQuorumVerifier());
- quorumPeer.setCnxnFactory(cnxnFactory);
- quorumPeer.setZKDatabase(new ZKDatabase(quorumPeer.getTxnFactory()));
- quorumPeer.setLearnerType(config.getPeerType());
- quorumPeer.start();
- quorumPeer.join();
- } catch (InterruptedException e) {
- // warn, but generally this is ok
- LOG.warn("Quorum Peer interrupted", e);
- }
- }
- }
在QuorumPeer的start函数中,先调用了loadDataBase方法用于恢复数据。启动与client交互的线程,并
- @Override
- public synchronized void start() {
- try {
- zkDb.loadDataBase();
- } catch(IOException ie) {
- LOG.fatal("Unable to load database on disk", ie);
- throw new RuntimeException("Unable to run quorum server ", ie);
- }
- cnxnFactory.start(); //用于处理与client的交互
- startLeaderElection();//开始选举算法
- super.start();
- }
调用loadDatabase从磁盘加载数据到内存
- public long loadDataBase() throws IOException {
- PlayBackListener listener=new PlayBackListener(){
- public void onTxnLoaded(TxnHeader hdr,Record txn){
- Request r = new Request(null, 0, hdr.getCxid(),hdr.getType(),
- null, null);
- r.txn = txn;
- r.hdr = hdr;
- r.zxid = hdr.getZxid();
- addCommittedProposal(r);
- }
- };
- long zxid = snapLog.restore(dataTree,sessionsWithTimeouts,listener);
- initialized = true;
- return zxid;
- }
调用QuorumPeer的run函数,按照peer的state做不同的处理
- @Override
- public void run() {
- setName("QuorumPeer:" + cnxnFactory.getLocalAddress());
- try {
- /*
- * Main loop
- */
- while (running) {
- switch (getPeerState()) {
- case LOOKING:
- try {
- LOG.info("LOOKING");
- setCurrentVote(makeLEStrategy().lookForLeader());
- } catch (Exception e) {
- LOG.warn("Unexpected exception",e);
- setPeerState(ServerState.LOOKING);
- }
- break;
- case OBSERVING:
- try {
- LOG.info("OBSERVING");
- setObserver(makeObserver(logFactory));
- observer.observeLeader();
- } catch (Exception e) {
- LOG.warn("Unexpected exception",e );
- } finally {
- observer.shutdown();
- setObserver(null);
- setPeerState(ServerState.LOOKING);
- }
- break;
- case FOLLOWING:
- try {
- LOG.info("FOLLOWING");
- setFollower(makeFollower(logFactory));
- follower.followLeader();
- } catch (Exception e) {
- LOG.warn("Unexpected exception",e);
- } finally {
- follower.shutdown();
- setFollower(null);
- setPeerState(ServerState.LOOKING);
- }
- break;
- case LEADING:
- LOG.info("LEADING");
- try {
- setLeader(makeLeader(logFactory));
- leader.lead();
- setLeader(null);
- } catch (Exception e) {
- LOG.warn("Unexpected exception",e);
- } finally {
- if (leader != null) {
- leader.shutdown("Forcing shutdown");
- setLeader(null);
- }
- setPeerState(ServerState.LOOKING);
- }
- break;
- }
- }
- }
- }
- http://blog.csdn.net/xhh198781/article/details/10949697
Zookeeper 源码分析-启动的更多相关文章
- zookeeper源码分析之五服务端(集群leader)处理请求流程
leader的实现类为LeaderZooKeeperServer,它间接继承自标准ZookeeperServer.它规定了请求到达leader时需要经历的路径: PrepRequestProcesso ...
- zookeeper源码分析之四服务端(单机)处理请求流程
上文: zookeeper源码分析之一服务端启动过程 中,我们介绍了zookeeper服务器的启动过程,其中单机是ZookeeperServer启动,集群使用QuorumPeer启动,那么这次我们分析 ...
- zookeeper源码分析之三客户端发送请求流程
znode 可以被监控,包括这个目录节点中存储的数据的修改,子节点目录的变化等,一旦变化可以通知设置监控的客户端,这个功能是zookeeper对于应用最重要的特性,通过这个特性可以实现的功能包括配置的 ...
- Symfony2源码分析——启动过程2
文章地址:http://www.hcoding.com/?p=46 上一篇分析Symfony2框架源码,探究Symfony2如何完成一个请求的前半部分,前半部分可以理解为Symfony2框架为处理请求 ...
- quartz2.x源码分析——启动过程
title: quartz2.x源码分析--启动过程 date: 2017-04-13 14:59:01 categories: quartz tags: [quartz, 源码分析] --- 先简单 ...
- mysql源码分析-启动过程
mysql源码分析-启动过程 概要 # sql/mysqld.cc, 不包含psi的初始化过程 mysqld_main: // 加载my.cnf和my.cnf.d,还有命令行参数 if (load_d ...
- apiserver源码分析——启动流程
前言 apiserver是k8s控制面的一个组件,在众多组件中唯一一个对接etcd,对外暴露http服务的形式为k8s中各种资源提供增删改查等服务.它是RESTful风格,每个资源的URI都会形如 / ...
- storm操作zookeeper源码分析-cluster.clj
storm操作zookeeper的主要函数都定义在命名空间backtype.storm.cluster中(即cluster.clj文件中).backtype.storm.cluster定义了两个重要p ...
- Symfony2源码分析——启动过程1
本文通过阅读分析Symfony2的源码,了解Symfony2启动过程中完成哪些工作,从阅读源码了解Symfony2框架. Symfony2的核心本质是把Request转换成Response的一个过程. ...
随机推荐
- ————————————————————————————杭电ACM————————————————X-POWER————————————————————————————————
_________________________________________我要成大牛!!!___________________________________________________ ...
- Net use命令
以指定账户密码建立网络磁盘 net use s: \\ip\ipc$ "密码" /user:“用户名”
- 13、C#基础整理(枚举)
枚举 1.概念和作用 (1)用于存放常量,只能在定义时赋值(防止编程过程中恶意篡改,并且防止对同一事物的不同赋值--统一化) (2)定义的枚举类型需要包含该类型的所有可能的值 (3)方法.类.内部都可 ...
- 6、网页制作Dreamweaver(HTML结构--dom操作)
一.基本语法:数据类型(字符串,小数,整数,布尔,时间) var, var s = "3.14"; var n = parseFloat(s); ; s += 5; var d = ...
- Centos 6.4 8250/16550 只生成了4个串口
/********************************************************************* * Centos 6.4 8250/16550 只生成了4 ...
- Lua标准库(转)
转载地址:http://www.yiibai.com/lua/lua_standard_libraries.html Lua的标准库提供了一组丰富的功能,与C的API直接实现,建立在Lua编程语言函数 ...
- vs2013 c++代码内出现中文导致编译错误
简单的做法就是,首先,菜单栏->文件->高级保存选项,选择utf-8 无签名, 然后,如果是发现注释语句里有中文,可以让注释语句与下行代码中间空一行, 如果是代码里有用到中文,那么就在中文 ...
- postgresql copy命令介绍
COPY 命令可以快速的导入数据到postgresql数据库中,文件格式类似TXT.CVS之类.适合批量导入数据,速度比较快.注意COPY只能用于表,不能用于视图. COPY 命令里面的文件必须是由服 ...
- Java 返回一个整数的各个数字之和的一种方法
public static long sumDigits(long n){ long total=0; long number=n; while(number!=0){ total=total+num ...
- twisted的defer模式和线程池
前言: 最近帮朋友review其模块服务代码, 使用的是python的twisted网络框架. 鉴于之前并没有使用过, 于是决定好好研究一番. twisted的reactor模型很好的处理了网络IO事 ...