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的一个过程. ...
随机推荐
- Ubuntu 修改IP地址网关
一.使用命令设置Ubuntu IP地址 1.修改配置文件blacklist.conf禁用IPV6 sudo vi /etc/modprobe.d/blacklist.conf 表示用vi编辑器(也可以 ...
- 帝国cms缩略图:网站不同地方生成不同的缩略图
本文转自:http://blog.sina.com.cn/s/blog_4d49ba58010115sd.html 方便网站多地方调用不同尺寸的缩略图. 根据图片源,在网站任意位置生成不同大小的缩略图 ...
- android定时更新文件
static变量在程序退出时不会清空的,除非系统内存不足以运行其他程序,才会清空.给SD卡上的文件过期时间.可以简单的在给文件命名时后面加个创建时间,在下次访问时判断是否需要更新.比如本来文件名是 i ...
- Android Packaging Problem
android Description Resource Path Location Type Error generating final archive: Debug Certificate ex ...
- Sed 直接修改文件
sed最常用的用法莫过于替换文件,然而其默认的模式是直接输出在shell中 sed 's/Old/New/' My_File.txt 如果我们想要sed直接在文件中更改,只需要在sed后面添加 -i ...
- 1130-host ... is not allowed to connect to this MySql server 开放mysql远程连接 不使用localhost
报错:1130-host ... is not allowed to connect to this MySql server 解决方法: 1. 改表法. 可能是你的帐号不允许从远程登陆,只能在loc ...
- 143. Reorder List
Given a singly linked list L: L0→L1→…→Ln-1→Ln,reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→… You must do thi ...
- BUTTON标签和INPUT标签的区别【转】
一句话概括主题:<button>具有<input type="button" ... >相同的作用但是在可操控性方面更加强大. HTML 4.01规范的Fo ...
- ES6 — 字符串String
ES6对字符串新增了一些函数和操作规范.下面我们来看ES6中对字符串新加的特性. 1.模版字符串 (即用反引号定义的字符串) 传统的字符串拼接通过我们使用'+'号与变量连接.例如: let name= ...
- android之官方下拉刷新组件SwipeRefreshLayout
1.setOnRefreshListener(SwipeRefreshLayout.OnRefreshListener listener):设置手势滑动监听器. 2.setProgressBackgr ...