Zookeeper 源码分析-启动

博客分类:

 

本文主要介绍了zookeeper启动的过程

运行zkServer.sh start命令可以启动zookeeper。入口的main函数在类中QuorumPeerMain。

main函数主要调用了runFromConfig函数,创建了QuorumPeer对象,并且调用了start函数,从而启动了zookeeper。

  1. public class QuorumPeerMain {
  2. protected QuorumPeer quorumPeer;
  3. /**
  4. * To start the replicated server specify the configuration file name on
  5. * the command line.
  6. * @param args path to the configfile
  7. */
  8. public static void main(String[] args) {
  9. QuorumPeerMain main = new QuorumPeerMain();
  10. main.initializeAndRun(args);
  11. }
  12. protected void initializeAndRun(String[] args)
  13. throws ConfigException, IOException
  14. {
  15. runFromConfig(config);
  16. }
  17. public void runFromConfig(QuorumPeerConfig config) throws IOException {
  18. LOG.info("Starting quorum peer");
  19. try {
  20. NIOServerCnxn.Factory cnxnFactory =
  21. new NIOServerCnxn.Factory(config.getClientPortAddress(),
  22. config.getMaxClientCnxns());
  23. quorumPeer = new QuorumPeer();
  24. quorumPeer.setClientPortAddress(config.getClientPortAddress());
  25. quorumPeer.setTxnFactory(new FileTxnSnapLog(
  26. new File(config.getDataLogDir()),
  27. new File(config.getDataDir())));
  28. quorumPeer.setQuorumPeers(config.getServers());
  29. quorumPeer.setElectionType(config.getElectionAlg());
  30. quorumPeer.setMyid(config.getServerId());
  31. quorumPeer.setTickTime(config.getTickTime());
  32. quorumPeer.setMinSessionTimeout(config.getMinSessionTimeout());
  33. quorumPeer.setMaxSessionTimeout(config.getMaxSessionTimeout());
  34. quorumPeer.setInitLimit(config.getInitLimit());
  35. quorumPeer.setSyncLimit(config.getSyncLimit());
  36. quorumPeer.setQuorumVerifier(config.getQuorumVerifier());
  37. quorumPeer.setCnxnFactory(cnxnFactory);
  38. quorumPeer.setZKDatabase(new ZKDatabase(quorumPeer.getTxnFactory()));
  39. quorumPeer.setLearnerType(config.getPeerType());
  40. quorumPeer.start();
  41. quorumPeer.join();
  42. } catch (InterruptedException e) {
  43. // warn, but generally this is ok
  44. LOG.warn("Quorum Peer interrupted", e);
  45. }
  46. }
  47. }

在QuorumPeer的start函数中,先调用了loadDataBase方法用于恢复数据。启动与client交互的线程,并

  1. @Override
  2. public synchronized void start() {
  3. try {
  4. zkDb.loadDataBase();
  5. } catch(IOException ie) {
  6. LOG.fatal("Unable to load database on disk", ie);
  7. throw new RuntimeException("Unable to run quorum server ", ie);
  8. }
  9. cnxnFactory.start(); //用于处理与client的交互
  10. startLeaderElection();//开始选举算法
  11. super.start();
  12. }

调用loadDatabase从磁盘加载数据到内存

  1. public long loadDataBase() throws IOException {
  2. PlayBackListener listener=new PlayBackListener(){
  3. public void onTxnLoaded(TxnHeader hdr,Record txn){
  4. Request r = new Request(null, 0, hdr.getCxid(),hdr.getType(),
  5. null, null);
  6. r.txn = txn;
  7. r.hdr = hdr;
  8. r.zxid = hdr.getZxid();
  9. addCommittedProposal(r);
  10. }
  11. };
  12. long zxid = snapLog.restore(dataTree,sessionsWithTimeouts,listener);
  13. initialized = true;
  14. return zxid;
  15. }

调用QuorumPeer的run函数,按照peer的state做不同的处理

  1. @Override
  2. public void run() {
  3. setName("QuorumPeer:" + cnxnFactory.getLocalAddress());
  4. try {
  5. /*
  6. * Main loop
  7. */
  8. while (running) {
  9. switch (getPeerState()) {
  10. case LOOKING:
  11. try {
  12. LOG.info("LOOKING");
  13. setCurrentVote(makeLEStrategy().lookForLeader());
  14. } catch (Exception e) {
  15. LOG.warn("Unexpected exception",e);
  16. setPeerState(ServerState.LOOKING);
  17. }
  18. break;
  19. case OBSERVING:
  20. try {
  21. LOG.info("OBSERVING");
  22. setObserver(makeObserver(logFactory));
  23. observer.observeLeader();
  24. } catch (Exception e) {
  25. LOG.warn("Unexpected exception",e );
  26. } finally {
  27. observer.shutdown();
  28. setObserver(null);
  29. setPeerState(ServerState.LOOKING);
  30. }
  31. break;
  32. case FOLLOWING:
  33. try {
  34. LOG.info("FOLLOWING");
  35. setFollower(makeFollower(logFactory));
  36. follower.followLeader();
  37. } catch (Exception e) {
  38. LOG.warn("Unexpected exception",e);
  39. } finally {
  40. follower.shutdown();
  41. setFollower(null);
  42. setPeerState(ServerState.LOOKING);
  43. }
  44. break;
  45. case LEADING:
  46. LOG.info("LEADING");
  47. try {
  48. setLeader(makeLeader(logFactory));
  49. leader.lead();
  50. setLeader(null);
  51. } catch (Exception e) {
  52. LOG.warn("Unexpected exception",e);
  53. } finally {
  54. if (leader != null) {
  55. leader.shutdown("Forcing shutdown");
  56. setLeader(null);
  57. }
  58. setPeerState(ServerState.LOOKING);
  59. }
  60. break;
  61. }
  62. }
  63. }
  64. }
  65. http://blog.csdn.net/xhh198781/article/details/10949697
04-15 21:35