[Zookeeper] 服務(wù)端之集群版服務(wù)器啟動(dòng)

1 集群版服務(wù)器啟動(dòng)流程

2 源碼解讀

2.1

  1. 執(zhí)行QuorumPeerMain的main方法半开,其中先創(chuàng)建一個(gè)QuorumPeerMain對(duì)象
  2. 調(diào)用initializeAndRun方法,在該方法里面走的是runFromConfig(config)丛忆,條件判斷是args.length == 1 && config.servers.size() > 0

config.servers配置

server.1=node1:12888:13888
server.2=node2:12888:13888
server.3=node3:12888:13888

12888主要用于leader和learner通信端口潘明;
13888主要用于FastLeaderElection的端口

最終調(diào)用的是QuorumPeerMainrunFromConfig方法

2.2 QuorumPeerMain中的runFromConfig

進(jìn)行一系列的屬性設(shè)置

 try {
          ServerCnxnFactory cnxnFactory = ServerCnxnFactory.createFactory();
          cnxnFactory.configure(config.getClientPortAddress(),
                                config.getMaxClientCnxns());
          // 構(gòu)造QuorumPeer對(duì)象
          quorumPeer = getQuorumPeer();

          quorumPeer.setQuorumPeers(config.getServers());
          quorumPeer.setTxnFactory(new FileTxnSnapLog(
                  new File(config.getDataLogDir()),
                  new File(config.getDataDir())));
          // 設(shè)置選舉算法
          quorumPeer.setElectionType(config.getElectionAlg());
          // 需要在data目錄下創(chuàng)建一個(gè)myid文件,標(biāo)識(shí)myid
          quorumPeer.setMyid(config.getServerId());
          quorumPeer.setTickTime(config.getTickTime());
          quorumPeer.setInitLimit(config.getInitLimit());
          quorumPeer.setSyncLimit(config.getSyncLimit());
          quorumPeer.setQuorumListenOnAllIPs(config.getQuorumListenOnAllIPs());
          quorumPeer.setCnxnFactory(cnxnFactory);
          // 集群驗(yàn)證器,主要完成判斷一組server在已給定的配置的server列表中,是否能夠構(gòu)成集群
          quorumPeer.setQuorumVerifier(config.getQuorumVerifier());
          quorumPeer.setClientPortAddress(config.getClientPortAddress());
          quorumPeer.setMinSessionTimeout(config.getMinSessionTimeout());
          quorumPeer.setMaxSessionTimeout(config.getMaxSessionTimeout());
          quorumPeer.setZKDatabase(new ZKDatabase(quorumPeer.getTxnFactory()));
          quorumPeer.setLearnerType(config.getPeerType());
          quorumPeer.setSyncEnabled(config.getSyncEnabled());

          // sets quorum sasl authentication configurations
          quorumPeer.setQuorumSaslEnabled(config.quorumEnableSasl);
          if(quorumPeer.isQuorumSaslAuthEnabled()){
              quorumPeer.setQuorumServerSaslRequired(config.quorumServerRequireSasl);
              quorumPeer.setQuorumLearnerSaslRequired(config.quorumLearnerRequireSasl);
              quorumPeer.setQuorumServicePrincipal(config.quorumServicePrincipal);
              quorumPeer.setQuorumServerLoginContext(config.quorumServerLoginContext);
              quorumPeer.setQuorumLearnerLoginContext(config.quorumLearnerLoginContext);
          }

          quorumPeer.setQuorumCnxnThreadsSize(config.quorumCnxnThreadsSize);
          quorumPeer.initialize();
          // 調(diào)用start方法
          quorumPeer.start();
          quorumPeer.join();
      } catch (InterruptedException e) {
          // warn, but generally this is ok
          LOG.warn("Quorum Peer interrupted", e);
      }

2.3 調(diào)用quorumPeer的start方法

    @Override
    public synchronized void start() {
        // 加載內(nèi)存數(shù)據(jù)庫(kù)
        loadDataBase();
        cnxnFactory.start();        
        startLeaderElection();
        super.start();
    }

loadDataBase()方法

  private void loadDataBase() {
        File updating = new File(getTxnFactory().getSnapDir(),
                                 UPDATING_EPOCH_FILENAME);
        try {
            // 這里與單機(jī)版一樣,調(diào)用snapshot的restore
            zkDb.loadDataBase();

            // 獲取內(nèi)存中即DataTree中最近的事務(wù)id
            long lastProcessedZxid = zkDb.getDataTree().lastProcessedZxid;
            // 根據(jù)zxid獲取epoch
            long epochOfZxid = ZxidUtils.getEpochFromZxid(lastProcessedZxid);
            try {
                // 有該文件的話(huà),獲取到并且與epochOfZxid比較
                currentEpoch = readLongFromFile(CURRENT_EPOCH_FILENAME);
                if (epochOfZxid > currentEpoch && updating.exists()) {
                    LOG.info("{} found. The server was terminated after " +
                             "taking a snapshot but before updating current " +
                             "epoch. Setting current epoch to {}.",
                             UPDATING_EPOCH_FILENAME, epochOfZxid);
                    setCurrentEpoch(epochOfZxid);
                    if (!updating.delete()) {
                        throw new IOException("Failed to delete " +
                                              updating.toString());
                    }
                }
            } catch(FileNotFoundException e) {
                // pick a reasonable epoch number
                // this should only happen once when moving to a
                // new code version
                currentEpoch = epochOfZxid;
                LOG.info(CURRENT_EPOCH_FILENAME
                        + " not found! Creating with a reasonable default of {}. This should only happen when you are upgrading your installation",
                        currentEpoch);
                writeLongToFile(CURRENT_EPOCH_FILENAME, currentEpoch);
            }
            if (epochOfZxid > currentEpoch) {
                throw new IOException("The current epoch, " + ZxidUtils.zxidToString(currentEpoch) + ", is older than the last zxid, " + lastProcessedZxid);
            }
            try {
                acceptedEpoch = readLongFromFile(ACCEPTED_EPOCH_FILENAME);
            } catch(FileNotFoundException e) {
                // pick a reasonable epoch number
                // this should only happen once when moving to a
                // new code version
                acceptedEpoch = epochOfZxid;
                LOG.info(ACCEPTED_EPOCH_FILENAME
                        + " not found! Creating with a reasonable default of {}. This should only happen when you are upgrading your installation",
                        acceptedEpoch);
                writeLongToFile(ACCEPTED_EPOCH_FILENAME, acceptedEpoch);
            }
            if (acceptedEpoch < currentEpoch) {
                throw new IOException("The accepted epoch, " + ZxidUtils.zxidToString(acceptedEpoch) + " is less than the current epoch, " + ZxidUtils.zxidToString(currentEpoch));
            }
        } catch(IOException ie) {
            LOG.error("Unable to load database on disk", ie);
            throw new RuntimeException("Unable to run quorum server ", ie);
        }
    }

cnxnFactory.start()與單機(jī)版的一致;
startLeaderElection()就是正式進(jìn)行Leader選舉

快速選舉方法見(jiàn)另外的文章

最后調(diào)用QuorumPeer的start方法,實(shí)際上就是調(diào)用其run方法匾嘱。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市稽物,隨后出現(xiàn)的幾起案子奄毡,更是在濱河造成了極大的恐慌,老刑警劉巖贝或,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件吼过,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡咪奖,警方通過(guò)查閱死者的電腦和手機(jī)盗忱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)羊赵,“玉大人趟佃,你說(shuō)我怎么就攤上這事∶两荩” “怎么了闲昭?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)靡挥。 經(jīng)常有香客問(wèn)我序矩,道長(zhǎng),這世上最難降的妖魔是什么跋破? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任簸淀,我火速辦了婚禮瓶蝴,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘租幕。我一直安慰自己舷手,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布劲绪。 她就那樣靜靜地躺著男窟,像睡著了一般。 火紅的嫁衣襯著肌膚如雪贾富。 梳的紋絲不亂的頭發(fā)上蝎宇,一...
    開(kāi)封第一講書(shū)人閱讀 51,688評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音祷安,去河邊找鬼姥芥。 笑死,一個(gè)胖子當(dāng)著我的面吹牛汇鞭,可吹牛的內(nèi)容都是我干的凉唐。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼霍骄,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼台囱!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起读整,我...
    開(kāi)封第一講書(shū)人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤簿训,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后米间,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體强品,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年屈糊,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了的榛。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡逻锐,死狀恐怖夫晌,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情昧诱,我是刑警寧澤晓淀,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站盏档,受9級(jí)特大地震影響凶掰,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一锄俄、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧勺拣,春花似錦奶赠、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至愤惰,卻和暖如春苇经,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背宦言。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工扇单, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人奠旺。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓蜘澜,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親响疚。 傳聞我的和親對(duì)象是個(gè)殘疾皇子鄙信,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容