實(shí)現(xiàn)類HDFS啟動(dòng)腳本為$HADOOP_HOME/sbin/start-dfs.sh,查看start-dfs.sh可以看出,namenode是通過bin/hdfs命令來啟動(dòng)$vistart-dfs.sh#namenodesNAMENODES=$($HADOOP_PREFIX/bin/hdfsgetconf-namenodes)echo"Startingnamenod" />

亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

hadoop2.5.2學(xué)習(xí)及實(shí)踐筆記(四)—— namenode

系統(tǒng) 2735 0

對(duì)namenode啟動(dòng)時(shí)的相關(guān)操作及相關(guān)類有一個(gè)大體了解,后續(xù)深入研究時(shí),再對(duì)本文進(jìn)行補(bǔ)充

?

>實(shí)現(xiàn)類

HDFS 啟動(dòng)腳本為 $HADOOP_HOME/sbin/start-dfs.sh ,查看 start-dfs.sh 可以看出, namenode 是通過 bin /hdfs 命令來啟動(dòng)

      $ 
      
        vi
      
        start-dfs.
      
        sh
      
      
        



# namenodes

NAMENODES
      
      =$($HADOOP_PREFIX/bin/hdfs getconf -
      
        namenodes)


      
      
        echo
      
      
        "
      
      
        Starting namenodes on [$NAMENODES]
      
      
        "
      
      
        "
      
      
        $HADOOP_PREFIX/sbin/hadoop-daemons.sh
      
      
        "
      
      
         \

  
      
      --config 
      
        "
      
      
        $HADOOP_CONF_DIR
      
      
        "
      
      
         \

  
      
      --hostnames 
      
        "
      
      
        $NAMENODES
      
      
        "
      
      
         \

  
      
      --script 
      
        "
      
      
        $bin/hdfs
      
      
        "
      
      
         start namenode $nameStartOpt

#
      
      ---------------------------------------------------------
    

?

查看 $HADOOP_HOME/bin/hdfs ,可以找到 namenode 啟動(dòng)所調(diào)用的 java 類。

      $ 
      
        vi
      
       bin/
      
        hdfs:




      
      
        if
      
       [ 
      
        "
      
      
        $COMMAND
      
      
        "
      
       = 
      
        "
      
      
        namenode
      
      
        "
      
       ] ; 
      
        then
      
      
        

  CLASS
      
      =
      
        '
      
      
        org.apache.hadoop.hdfs.server.namenode.NameNode
      
      
        '
      
      
        

  HADOOP_OPTS
      
      =
      
        "
      
      
        $HADOOP_OPTS $HADOOP_NAMENODE_OPTS
      
      
        "
      
    

?

>源碼查看

按照前文 hadoop2.5.2學(xué)習(xí)及實(shí)踐筆記(二)—— 編譯源代碼及導(dǎo)入源碼至 eclipse 步驟,源碼已經(jīng)導(dǎo)入到 eclipse 中,快捷鍵 ctrl +shift+R 搜索并打開 NameNode .java 查看源碼

?

NameNode 類中有一個(gè)靜態(tài)代碼塊,表示在加載器加載 NameNode 類過程中的準(zhǔn)備階段,就會(huì)執(zhí)行代碼塊中的代碼。 HdfsConfiguration init () 方法的方法體是空的,這里的作用是觸發(fā)對(duì) HdfsConfiguration 的主動(dòng)調(diào)用,從而保證在執(zhí)行 NameNode 類相關(guān)調(diào)用時(shí),如果 HdfsConfiguration 類沒有被加載和初始化,先觸發(fā) HdfsConfiguration 的初始化過程。

      
        //
      
      
        org.apache.hadoop.hdfs.server.namenode.NameNode.java
      
      
        static
      
      
        {

     
      
      
        //
      
      
        HdfsConfiguration類init()方法:public static void init() {}
      
      
            HdfsConfiguration.init();

}
      
    

?

查看其 main 方法,可以看出 namenode 相關(guān)操作的主要入口方法是 createNameNode ( String argv[], Configuration conf ) 方法。

      
        //
      
      
        org.apache.hadoop.hdfs.server.namenode.NameNode.java
      
      
        public
      
      
        static
      
      
        void
      
       main(String argv[]) 
      
        throws
      
      
         Exception {

    
      
      
        if
      
       (DFSUtil.parseHelpArgument(argv, NameNode.USAGE, System.out, 
      
        true
      
      
        )) {

      System.exit(
      
      0
      
        );

    }



    
      
      
        try
      
      
         {

      
      
      
        //
      
      
        打印namenode啟動(dòng)或關(guān)閉日志信息
      
      

      StringUtils.startupShutdownMessage(NameNode.
      
        class
      
      
        , argv, LOG);

     
      
      
        //
      
      
        namenode相關(guān)主要操作
      
      

      NameNode namenode = 
      
        
          
            createNameNode
          
        
      
      (argv, 
      
        null
      
      
        );

      
      
      
        if
      
       (namenode != 
      
        null
      
      
        ) {

          
      
      
        //
      
      
        向客戶端和datanode提供RPC服務(wù),直到RPC服務(wù)器結(jié)束運(yùn)行
      
      
                namenode.join();

      }

    } 
      
      
        catch
      
      
         (Throwable e) {

      LOG.fatal(
      
      "Exception in namenode join"
      
        , e);

      terminate(
      
      1
      
        , e);

    }

  }
      
    

?

createNameNode 方法中通過一個(gè) switch 語句對(duì)不同的命令執(zhí)行不同的操作。比如搭建環(huán)境時(shí)格式化文件系統(tǒng)時(shí)的操作,可以查看FORMAT分支。

      
        //
      
      
        org.apache.hadoop.hdfs.server.namenode.NameNode.java
      
      
        public
      
      
        static
      
      
         NameNode 
        
          
            
              createNameNode
            
          
        
        (String argv[], Configuration conf)

      
      
      
        throws
      
      
         IOException {

    LOG.info(
      
      "createNameNode " +
      
         Arrays.asList(argv));

    
      
      
        if
      
       (conf == 
      
        null
      
      
        )

      conf 
      
      = 
      
        new
      
      
         HdfsConfiguration();

    
      
      
        //
      
      
        參數(shù)為空時(shí)默認(rèn): -regular
      
      

    StartupOption startOpt =
      
         parseArguments(argv);

    
      
      
        if
      
       (startOpt == 
      
        null
      
      
        ) {

      printUsage(System.err);

      
      
      
        return
      
      
        null
      
      
        ;

    }

    setStartupOption(conf, startOpt);

    

    
      
      
        switch
      
      
         (startOpt) {

      
      
      
        case
      
       FORMAT: {
      
        //
      
      
        格式化文件系統(tǒng),偽分布式環(huán)境搭建時(shí)調(diào)用過namenode -format命令
      
      
        boolean
      
       aborted =
      
         format(conf, startOpt.getForceFormat(),

            startOpt.getInteractiveFormat());

        terminate(aborted 
      
      ? 1 : 0
      
        );

        
      
      
        return
      
      
        null
      
      ; 
      
        //
      
      
         avoid javac warning
      
      
              }

      
      
      
        case
      
      
         GENCLUSTERID: {

        System.err.println(
      
      "Generating new cluster id:"
      
        );

        System.out.println(NNStorage.newClusterID());

        terminate(
      
      0
      
        );

        
      
      
        return
      
      
        null
      
      
        ;

      }

      
      
      
        case
      
      
         FINALIZE: {

        System.err.println(
      
      "Use of the argument '" + StartupOption.FINALIZE +

            "' is no longer supported. To finalize an upgrade, start the NN " +

            " and then run `hdfs dfsadmin -finalizeUpgrade'"
      
        );

        terminate(
      
      1
      
        );

        
      
      
        return
      
      
        null
      
      ; 
      
        //
      
      
         avoid javac warning
      
      
              }

      
      
      
        case
      
      
         ROLLBACK: {

        
      
      
        boolean
      
       aborted = doRollback(conf, 
      
        true
      
      
        );

        terminate(aborted 
      
      ? 1 : 0
      
        );

        
      
      
        return
      
      
        null
      
      ; 
      
        //
      
      
         avoid warning
      
      
              }

      
      
      
        case
      
      
         BOOTSTRAPSTANDBY: {

        String toolArgs[] 
      
      = Arrays.copyOfRange(argv, 1
      
        , argv.length);

        
      
      
        int
      
       rc =
      
         BootstrapStandby.run(toolArgs, conf);

        terminate(rc);

        
      
      
        return
      
      
        null
      
      ; 
      
        //
      
      
         avoid warning
      
      
              }

      
      
      
        case
      
      
         INITIALIZESHAREDEDITS: {

        
      
      
        boolean
      
       aborted =
      
         initializeSharedEdits(conf,

            startOpt.getForceFormat(),

            startOpt.getInteractiveFormat());

        terminate(aborted 
      
      ? 1 : 0
      
        );

        
      
      
        return
      
      
        null
      
      ; 
      
        //
      
      
         avoid warning
      
      
              }

      
      
      
        case
      
      
         BACKUP:

      
      
      
        case
      
       CHECKPOINT: {
      
        //
      
      
        backupnode和checkpointnode啟動(dòng)
      
      

        NamenodeRole role =
      
         startOpt.toNodeRole();

        DefaultMetricsSystem.initialize(role.toString().replace(
      
      " ", ""
      
        ));

          
      
      
        //
      
      
        backupnode繼承NameNode類,代碼最終執(zhí)行的還是NameNode的構(gòu)造方法
      
      
        return
      
      
        new
      
      
         BackupNode(conf, role);

      }

      
      
      
        case
      
      
         RECOVER: {

        NameNode.doRecovery(startOpt, conf);

        
      
      
        return
      
      
        null
      
      
        ;

      }

      
      
      
        case
      
      
         METADATAVERSION: {

        printMetadataVersion(conf);

        terminate(
      
      0
      
        );

        
      
      
        return
      
      
        null
      
      ; 
      
        //
      
      
         avoid javac warning
      
      
              }

      
      
      
        default
      
      
        : {

        DefaultMetricsSystem.initialize(
      
      "NameNode"
      
        );

          
      
      
        //
      
      
        啟動(dòng)時(shí)startOpt=“-regular”,代碼執(zhí)行default分支,通過構(gòu)造函數(shù)返回一個(gè)namenode實(shí)例
      
      
        return
      
      
        new
      
      
        
          
            
               NameNode(conf); 
            
          
        
              }

    }

  }
      
    

?

namenode 的構(gòu)造方法

      
        //
      
      
        org.apache.hadoop.hdfs.server.namenode.NameNode.java
      
      
        public
      
       NameNode(Configuration conf) 
      
        throws
      
      
         IOException {

    
      
      
        this
      
      
        (conf, NamenodeRole.NAMENODE);

  }

 
      
      
        protected
      
      
         NameNode(Configuration conf, NamenodeRole role) 

      
      
      
        throws
      
      
         IOException { 

    
      
      
        this
      
      .conf =
      
         conf;

    
      
      
        this
      
      .role =
      
         role;

    
      
      
        //
      
      
        獲取fs.defaultFS,設(shè)置namenode地址
      
      
            setClientNamenodeAddress(conf);

    String nsId 
      
      =
      
         getNameServiceId(conf);

    String namenodeId 
      
      =
      
         HAUtil.getNameNodeId(conf, nsId);

    
      
      
        //
      
      
        是否啟用HA
      
      
        this
      
      .haEnabled =
      
         HAUtil.isHAEnabled(conf, nsId);

    
      
      
        //
      
      
        HA狀態(tài):?jiǎn)⒂?備用
      
      

    state =
      
         createHAState(getStartupOption(conf));

    
      
      
        //
      
      
        讀取dfs.ha.allow.stale.reads,設(shè)置namenode在備用狀態(tài)時(shí)是否允許讀操作,默認(rèn)為false
      
      
        this
      
      .allowStaleStandbyReads =
      
         HAUtil.shouldAllowStandbyReads(conf);

    
      
      
        this
      
      .haContext =
      
         createHAContext();

    
      
      
        try
      
      
         {

     
      
      
        //
      
      
        聯(lián)邦環(huán)境下,使用該方法配置一系列使用一個(gè)邏輯上的nsId組合在一起的namenode
      
      
              initializeGenericKeys(conf, nsId, namenodeId);

    
      
      
        //
      
      
        namenode初始化      
      
      
        
          
             initialize(conf); 
          
        
      
      
        try
      
      
         {

        haContext.writeLock();

        state.prepareToEnterState(haContext);

        
      
      
        //
      
      
        namenode進(jìn)入相應(yīng)狀態(tài):active state/backup state/standby state
      
      
               state.enterState(haContext);

      } 
      
      
        finally
      
      
         {

        haContext.writeUnlock();

      }

    } 
      
      
        catch
      
      
         (IOException e) {

      
      
      
        this
      
      
        .stop();

      
      
      
        throw
      
      
         e;

    } 
      
      
        catch
      
      
         (HadoopIllegalArgumentException e) {

      
      
      
        this
      
      
        .stop();

      
      
      
        throw
      
      
         e;

    }

  }
      
    

?

namenode初始化方法代碼

      
        //
      
      
        org.apache.hadoop.hdfs.server.namenode.NameNode.java
      
      
        protected
      
      
        void
      
      
        
          
            initialize
          
        
      
      (Configuration conf) 
      
        throws
      
      
         IOException {

    
      
      
        if
      
       (conf.get(HADOOP_USER_GROUP_METRICS_PERCENTILES_INTERVALS) == 
      
        null
      
      
        ) {

      String intervals 
      
      =
      
         conf.get(DFS_METRICS_PERCENTILES_INTERVALS_KEY);

      
      
      
        if
      
       (intervals != 
      
        null
      
      
        ) {

        conf.set(HADOOP_USER_GROUP_METRICS_PERCENTILES_INTERVALS,

          intervals);

      }

    }

    
      
      
        //
      
      
        設(shè)置權(quán)限,根據(jù)hadoop.security.authentication獲取認(rèn)證方式及規(guī)則
      
      
            UserGroupInformation.setConfiguration(conf);

    
      
      
        //
      
      
        登錄:如果認(rèn)證方式為simple則退出該方法     

    
      
      
        //
      
      
        否則調(diào)用UserGroupInformation.loginUserFromKeytab進(jìn)行登陸,登陸使用dfs.namenode.kerberos.principal作為用戶名
      
      
            loginAsNameNodeUser(conf);



    
      
      
        //
      
      
        初始化度量系統(tǒng),用于度量namenode服務(wù)狀態(tài)
      
      

    NameNode.initMetrics(conf, 
      
        this
      
      
        .getRole());

    StartupProgressMetrics.register(startupProgress);



    
      
      
        if
      
       (NamenodeRole.NAMENODE ==
      
         role) {

      
      
      
        //
      
      
        啟動(dòng)http服務(wù)器
      
      
              startHttpServer(conf);

    }

    
      
      
        //根據(jù)命令對(duì)命名空間進(jìn)行操作,如:前文所述啟動(dòng)時(shí)
      
      
        加載本地命名空間鏡像和應(yīng)用編輯日志,在內(nèi)存中建立命名空間的映像
      
      
        
          
             loadNamesystem(conf); 
          
        
      
      
        //
      
      
        創(chuàng)建RPC服務(wù)器
      
      

    rpcServer =
      
         createRpcServer(conf);

    
      
      
        if
      
       (clientNamenodeAddress == 
      
        null
      
      
        ) {

      
      
      
        //
      
      
         This is expected for MiniDFSCluster. Set it now using 

      
      
      
        //
      
      
         the RPC server's bind address.
      
      

      clientNamenodeAddress =
      
         

          NetUtils.getHostPortString(rpcServer.getRpcAddress());

      LOG.info(
      
      "Clients are to use " + clientNamenodeAddress + " to access"

          + " this namenode/service."
      
        );

    }

    
      
      
        if
      
       (NamenodeRole.NAMENODE ==
      
         role) {

      httpServer.setNameNodeAddress(getNameNodeAddress());

      httpServer.setFSImage(getFSImage());

    }

    

    pauseMonitor 
      
      = 
      
        new
      
      
         JvmPauseMonitor(conf);

    pauseMonitor.start();

    metrics.getJvmMetrics().setPauseMonitor(pauseMonitor);

    

    
      
      
        //
      
      
        啟動(dòng)活動(dòng)狀態(tài)和備用狀態(tài)的公共服務(wù):RPC服務(wù)和namenode的插件程序啟動(dòng)
      
      
            startCommonServices(conf);

  }
      
    

?

loadNamesystem(Configuration conf) 方法調(diào)用 FSNamesystem 類的 loadFromDisk(Configuration conf) 。前文提到的, namenode 啟動(dòng)時(shí)從本地文件系統(tǒng)加載鏡像并重做編輯日志,都在此方法中實(shí)現(xiàn)。

      
        //
      
      
        org.apache.hadoop.hdfs.server.namenode.FSNamesystem.java
      
      
        static
      
       FSNamesystem
      
        
          
             loadFromDisk
          
        
      
      (Configuration conf) 
      
        throws
      
      
         IOException {

    
      
      
        //
      
      
        必須的編輯日志目錄檢查
      
      
            checkConfiguration(conf);

    
      
      
        //
      
      
        設(shè)在NNStorage,并初始化編輯日志目錄。NNStorage主要功能是管理namenode使用的存儲(chǔ)目錄
      
      

    FSImage fsImage = 
      
        new
      
      
         FSImage(conf,

        FSNamesystem.getNamespaceDirs(conf),

        FSNamesystem.getNamespaceEditsDirs(conf));

    
      
      
        //
      
      
        根據(jù)指定的鏡像創(chuàng)建FSNamesystem對(duì)象
      
      

    FSNamesystem namesystem = 
      
        new
      
       FSNamesystem(conf, fsImage, 
      
        false
      
      
        );

    StartupOption startOpt 
      
      =
      
         NameNode.getStartupOption(conf);
        
if (startOpt == StartupOption.RECOVER) { namesystem.setSafeMode(SafeModeAction.SAFEMODE_ENTER); } long loadStart = now(); try { // 加載鏡像、重做編輯日志,并打開一個(gè)新編輯文件都在此方法中 namesystem.loadFSImage(startOpt); } catch (IOException ioe) { LOG.warn( "Encountered exception loading fsimage" , ioe); fsImage.close(); throw ioe; } long timeTakenToLoadFSImage = now() - loadStart; LOG.info( "Finished loading FSImage in " + timeTakenToLoadFSImage + " msecs" ); NameNodeMetrics nnMetrics = NameNode.getNameNodeMetrics(); if (nnMetrics != null ) { nnMetrics.setFsImageLoadTime(( int ) timeTakenToLoadFSImage); } return namesystem; } private void loadFSImage (StartupOption startOpt) throws IOException { final FSImage fsImage = getFSImage(); // format before starting up if requested if (startOpt == StartupOption.FORMAT) { fsImage.format( this , fsImage.getStorage().determineClusterId()); // reuse current id startOpt = StartupOption.REGULAR; } boolean success = false ; writeLock(); try { // We shouldn't be calling saveNamespace if we've come up in standby state. MetaRecoveryContext recovery = startOpt.createRecoveryContext(); final boolean staleImage = fsImage.recoverTransitionRead(startOpt, this, recovery); if (RollingUpgradeStartupOption.ROLLBACK.matches(startOpt)) { rollingUpgradeInfo = null ; } final boolean needToSave = staleImage && !haEnabled && ! isRollingUpgrade(); LOG.info( "Need to save fs image? " + needToSave + " (staleImage=" + staleImage + ", haEnabled=" + haEnabled + ", isRollingUpgrade=" + isRollingUpgrade() + ")" ); if (needToSave) { fsImage.saveNamespace( this ); } else { // No need to save, so mark the phase done. StartupProgress prog = NameNode.getStartupProgress(); prog.beginPhase(Phase.SAVING_CHECKPOINT); prog.endPhase(Phase.SAVING_CHECKPOINT); } // This will start a new log segment and write to the seen_txid file, so // we shouldn't do it when coming up in standby state if (!haEnabled || (haEnabled && startOpt == StartupOption.UPGRADE)) { fsImage.openEditLogForWrite(); } success = true ; } finally { if (! success) { fsImage.close(); } writeUnlock(); } imageLoadComplete(); }

?

hadoop2.5.2學(xué)習(xí)及實(shí)踐筆記(四)—— namenode啟動(dòng)過程源碼概覽


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 久久久久国产精品 | 国产精品成人麻豆专区 | 亚洲精品高清在线 | 亚洲精品视频久久久 | 色视屏 | 亚洲第一综合网站 | 国产成人精品一区二三区 | 欧美激情亚洲 | 中国大陆高清aⅴ毛片 | 在线观看国产情趣免费视频 | 一级毛片一级毛片一级毛片aa | 九九视频九九 | 一级激情视频 | 久久lu| 视频国产在线 | 国产美女mm131爽爽爽免费 | 国产成人综合网亚洲欧美在线 | 九九精品国产 | 四虎永久在线精品国产馆v视影院 | 日本免费在线一区 | 免费亚洲成人 | 四虎影视库国产精品一区 | 久久久久久久久久久福利观看 | 欧美亚洲高清 | 亚洲日本一区二区三区高清在线 | 精品免费久久久久久久 | 按摩毛片| 久久亚洲欧美 | 天天干夜夜爱 | 亚洲国产欧美在线 | 在线亚洲国产精品区 | 国产真实偷乱视频在线观看 | 国产精品2020在线看亚瑟 | 在线视频这里只有精品 | 老司机午夜免费影院 | 国产精品国产福利国产秒拍 | 综合图区亚洲 | 欧美va亚洲va在线观看蝴蝶网 | 精品亚洲无人区一区二区 | 成人a毛片在线看免费全部播放 | 亚洲免费中文 |