1、NameNode启动流程的初始化操作

阅读源码第一步是要编译源码;

源码版本:hadoop2.6+ ~ hadoop2.7 这个范围均可,改动不是特别大

编译源码教程连接:https://www.jianshu.com/p/a66ab0235fb9

https://www.cnblogs.com/hequn/articles/4839689.html

ps. 编译出错很常见不要慌 ,只要确保hadoop需要的依赖是正确的(比如protocol),就没问题!

1、查看源码NameNode类

在namenode中有一段main函数,说明 我们通过命令启动namenode的时候,肯定是通过这个main函数来执行的(脚本:hadoop-daemon.sh  、hdfs):

 1 public static void main(String argv[]) throws Exception {
 2     if (DFSUtil.parseHelpArgument(argv, NameNode.USAGE, System.out, true)) {
 3       System.out.println("####参数校验#####");
 4       System.exit(0);
 5       //hadooop namenode -format
 6       //hadoop -datemon.sh start namenode
 7       //hadoop-datemon.sh start nn
 8     }
 9
10     try {
11       //启动打印日志
12       StringUtils.startupShutdownMessage(NameNode.class, argv, LOG);
13       //TODO 创建NameNode核心代码
14       NameNode namenode = createNameNode(argv, null);
15       if (namenode != null) {
16         //就是线程的join
17         //会使主线程进入等待池并等待t线程执行完毕后才会被唤醒
18         namenode.join();
19       }
20     } catch (Throwable e) {
21       LOG.error("Failed to start namenode.", e);
22       terminate(1, e);
23     }
24   }

2、查看核心代码:createNameNode

NameNode namenode = createNameNode(argv, null);

点击进入createNameNode(argv , null)函数

显然我们是启动namenode,所有都匹配不上,因此会走最后一段

 1 public static NameNode createNameNode(String argv[], Configuration conf)
 2       throws IOException {
 3     LOG.info("createNameNode " + Arrays.asList(argv));
 4     if (conf == null)
 5       conf = new HdfsConfiguration();
 6     StartupOption startOpt = parseArguments(argv);
 7     if (startOpt == null) {
 8       printUsage(System.err);
 9       return null;
10     }
11     //将启动参数加入到配置中
12     setStartupOption(conf, startOpt);
13     /**
14      * 我们在集群中操作 , 比如 :
15      * hdfs namenode -format
16      * hadoop fs -put XXX /
17      * 正常情况下,是先启动namenode
18      * hadoop-daemon.sh start namenode
19      * */
20     switch (startOpt) {
21       //格式化
22       case FORMAT: {//hadoop namenode -format
23         boolean aborted = format(conf, startOpt.getForceFormat(),
24                 startOpt.getInteractiveFormat());
25         terminate(aborted ? 1 : 0);
26         return null; // avoid javac warning
27       }
28       // 产生集群ID.
29       case GENCLUSTERID: {
30         System.err.println("Generating new cluster id:");
31         System.out.println(NNStorage.newClusterID());
32         terminate(0);
33         return null;
34       }
35       //定版本
36       case FINALIZE: {
37         System.err.println("Use of the argument ‘" + StartupOption.FINALIZE +
38                 "‘ is no longer supported. To finalize an upgrade, start the NN " +
39                 " and then run `hdfs dfsadmin -finalizeUpgrade‘");
40         terminate(1);
41         return null; // avoid javac warning
42       }
43       //回滚
44       case ROLLBACK: {
45         boolean aborted = doRollback(conf, true);
46         terminate(aborted ? 1 : 0);
47         return null; // avoid warning
48       }
49       //同步active节点的快照(配置完HA需要运行这个命令同步active节点的快照(配置完HA需要运行这个命令
50       case BOOTSTRAPSTANDBY: {
51         String toolArgs[] = Arrays.copyOfRange(argv, 1, argv.length);
52         int rc = BootstrapStandby.run(toolArgs, conf);
53         terminate(rc);
54         return null; // avoid warning
55       }
56       //向备用节点共享一组edits日志
57       case INITIALIZESHAREDEDITS: {
58         boolean aborted = initializeSharedEdits(conf,
59                 startOpt.getForceFormat(),
60                 startOpt.getInteractiveFormat());
61         terminate(aborted ? 1 : 0);
62         return null; // avoid warning
63       }
64       //启动冷备或者温备名字节点
65       case BACKUP:
66       case CHECKPOINT: {
67         NamenodeRole role = startOpt.toNodeRole();
68         DefaultMetricsSystem.initialize(role.toString().replace(" ", ""));
69         return new BackupNode(conf, role);
70       }
71       //恢复损坏的元数据以及文件系统
72       case RECOVER: {
73         NameNode.doRecovery(startOpt, conf);
74         return null;
75       }
76       //检查配置的正确性
77       case METADATAVERSION: {
78         printMetadataVersion(conf);
79         terminate(0);
80         return null; // avoid javac warning
81       }
82       //以升级的方式启动
83       case UPGRADEONLY: {
84         DefaultMetricsSystem.initialize("NameNode");
85         new NameNode(conf);
86         terminate(0);
87         return null;
88       }
89       //正常启动NameNode
90       default: {
91         //初始化metric系统
92         DefaultMetricsSystem.initialize("NameNode");
93         //TODO
94         return new NameNode(conf);
95       }
96     }
97   }

NameNode这个类,里面有一些成员变量,还是很重要,很常见的;比如

 1 //NameNode核心成员变量用来管理元数据(实现对DataNode、Block的管理以及读写日志)
 2   protected FSNamesystem namesystem;
 3   //保存配置文件的信息
 4   protected final Configuration conf;
 5   //保存NameNode的角色信息
 6   protected final NamenodeRole role;
 7   //保存NameNode的状态(HA)
 8   private volatile HAState state;
 9   //是否开启了高可用(HA)
10   private final boolean haEnabled;
11   //高可用上下文
12   private final HAContext haContext;
13   //NameNode核心成员变量提供RPC服务(提供RPC服务是DataNode和NameNode通信和外部命令管理NameNode的窗口)
14   private NameNodeRpcServer rpcServer;

在这个Namenode的构造参数里面,主要是:

1、对namenode做参数的设置(fs.defaultFS、rpc地址等)

2、初始化

3、根据初始化处理的结果,namenode进入对应的状态(active、backup、standby)

 1 /**
 2    * 1、对namenode做参数的注册(fs.defaultFS、rpc地址等)
 3    * 2、初始化
 4    * 3、根据初始化处理的结果,namenode进入对应的状态(active、backup、standby)
 5    * */
 6   protected NameNode(Configuration conf, NamenodeRole role)
 7       throws IOException {
 8     this.conf = conf;
 9     this.role = role;//保存NameNode的角色信息
10     //设置clients访问nomenode或nameservice的访问地址  配置项fs.defaultFS:hadoop01:9000
11     setClientNamenodeAddress(conf);
12     String nsId = getNameServiceId(conf);
13     String namenodeId = HAUtil.getNameNodeId(conf, nsId);
14     //ha相关
15     this.haEnabled = HAUtil.isHAEnabled(conf, nsId);
16     //根据用户设置的启动参数,确定启动以后的初始状态,如果是正常启动,则全部直接进入Standby状态
17     state = createHAState(getStartupOption(conf));
18     this.allowStaleStandbyReads = HAUtil.shouldAllowStandbyReads(conf);
19     //TODO 在创建HA的时候,也启动了standByNameNode的服务
20     this.haContext = createHAContext();
21
22
23
24     try {
25       //给联邦模式下准备的,主要是设置联邦模式下namenode的地址和RPC地址
26       initializeGenericKeys(conf, nsId, namenodeId);
27       //TODO
28       initialize(conf);
29       // HA相关
30       try {
31         haContext.writeLock();
32         state.prepareToEnterState(haContext);
33         state.enterState(haContext);
34       } finally {
35         haContext.writeUnlock();
36       }
37     } catch (IOException e) {
38       this.stop();
39       throw e;
40     } catch (HadoopIllegalArgumentException e) {
41       this.stop();
42       throw e;
43     }
44     this.started.set(true);
45   }

那么关键信息 就是initialize,所以我们接下来重点来看initialize

initialize代码块包含了:

1、metrics监控的信息设置
2、hadoop的kerberos的安全认证
3、启动namendoe的web服务
4、加载元数据
5、创建RPC
6、启动公共服务startCommonServices (比如:启动RPC , 启动磁盘资源检查线程等工作)

具体内容,下一篇介绍

原文地址:https://www.cnblogs.com/niutao/p/12609621.html

时间: 2024-11-01 21:40:45

1、NameNode启动流程的初始化操作的相关文章

SpringMVC源码解析-DispatcherServlet启动流程和初始化

在使用springmvc框架,会在web.xml文件配置一个DispatcherServlet,这正是web容器开始初始化,同时会在建立自己的上下文来持有SpringMVC的bean对象. 先从DispatcherServlet入手,从名字来看,它是一个Servlet.它的定义如下: public class DispatcherServlet extends FrameworkServlet { 它是继承FrameworkServlet,来看一下整个的继承关系. 从继承关系来看,Dispatc

hadoop2.5.2学习及实践笔记(四)—— namenode启动过程源码概览

对namenode启动时的相关操作及相关类有一个大体了解,后续深入研究时,再对本文进行补充 >实现类 HDFS启动脚本为$HADOOP_HOME/sbin/start-dfs.sh,查看start-dfs.sh可以看出,namenode是通过bin/hdfs命令来启动 $ vi start-dfs.sh # namenodes NAMENODES=$($HADOOP_PREFIX/bin/hdfs getconf -namenodes) echo "Starting namenodes o

Centos启动流程及grub legacy

Linux系统的组成部分:内核+根文件系统 内核的功能:进程管理.内存管理.网络管理.文件系统.驱动程序.安全功能 系统在运行时要么就是在运行内核代码,要么就是在运行应用程序代码.如果一个程序大多数时间在内核的系统调用上,那样真正执行业务功能的时间就少了,实际生产力不大.通常在开发程序的时候,大都不是直接使用系统调用来实现功能,而是使用系统调用的二次封装(glibc库),所谓库,就是函数(功能)的集合,库中的函数名,能够接受的参数,参数类型都应该有定义(头文件). 库也是二进制程序,但是相比正常

第1章 ZigBee协议栈初始化网络启动流程

作者:宋老师,华清远见嵌入式学院讲师. ZigBee的基本流程:由协调器的组网(创建PAN ID),终端设备和路由设备发现网络以及加入网络. 基本流程:main()->osal_init_system()->osalInitTasks()->ZDApp_Init(),进协议栈初始化函数ZDApp_Init(). 1.1 进入程序入口main(). ZMain.c中 C++ Code int main( void )         {                 // Turn of

①操作系统安装流程及初始化规范

v1.0-陈泰成-20180306v1.1-陈泰成-20180320 操作系统安装流程 1 ) 调用cobbler-api安装操作系统2 ) 调用saltstack-api进行系统初始化3 ) 调用dns-api解析主机名4 ) 调用zabbix-api对该新上线机器加上监控5 ) 再次调用saltstack-api部署软件(安装Nginx\PHP)6 ) 调用deploy-api将当前版本的代码部署到服务器上7 ) 调用test-api测试当前服务运行是否正常8 ) 调用slb-api将该节点

linux -小记(1) 问题:"linux ifconfig查看网卡名称与配置文件不否" 或 启动网卡提示“ eth0 似乎不存在, 初始化操作将被延迟”。

"linux ifconfig查看网卡名称与配置文件不否" 或 启动网卡提示" eth0 似乎不存在, 初始化操作将被延迟" . 问题 1. service network restart 重启网卡 提示错误: "eth0 似乎不存在, 初始化操作将被延迟"  .. ping 某一个网址可通 查看网卡配置文件ifconfig 发现我的配置文件, cd /etc/sysconfig/network-scripts/ifcfg-Auto_eth0是这

Netty源码分析第1章(Netty启动流程)-------->第1节: 服务端初始化

第一章:  Server启动流程 概述: 本章主要讲解server启动的关键步骤, 读者只需要了解server启动的大概逻辑, 知道关键的步骤在哪个类执行即可, 并不需要了解每一步的运作机制, 之后会对每个模块进行深度分析 第一节:服务端初始化 首先看下在我们用户代码中netty的使用最简单的一个demo: EventLoopGroup bossGroup = new NioEventLoopGroup(1); EventLoopGroup workerGroup = new NioEventL

SpringBoot启动流程分析(四):IoC容器的初始化过程

SpringBoot系列文章简介 SpringBoot源码阅读辅助篇: Spring IoC容器与应用上下文的设计与实现 SpringBoot启动流程源码分析: SpringBoot启动流程分析(一):SpringApplication类初始化过程 SpringBoot启动流程分析(二):SpringApplication的run方法 SpringBoot启动流程分析(三):SpringApplication的run方法之prepareContext()方法 SpringBoot启动流程分析(四

camunda流程实例启动的一些简单操作

public class ZccRuntimeService { RuntimeService runtimeService; RepositoryService repositoryService; @Before public void init(){ ProcessEngineConfiguration processEngineConfiguration = ProcessEngineConfiguration.createProcessEngineConfigurationFromRe