千家信息网

Hadoop之启动文件namenode原理的示例分析

发表于:2025-01-18 作者:千家信息网编辑
千家信息网最后更新 2025年01月18日,这篇文章主要为大家展示了"Hadoop之启动文件namenode原理的示例分析",内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下"Hadoop之启动文件name
千家信息网最后更新 2025年01月18日Hadoop之启动文件namenode原理的示例分析

这篇文章主要为大家展示了"Hadoop之启动文件namenode原理的示例分析",内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下"Hadoop之启动文件namenode原理的示例分析"这篇文章吧。

1、 namenode启动

在本系列文章三中分析了hadoop的启动文件,其中提到了namenode启动的时候调用的类为

org.apache.hadoop.hdfs.server.namenode.NameNode

其main方法的内容如下:

 public static void main(String argv[]) throws Exception {    if (DFSUtil.parseHelpArgument(argv, NameNode.USAGE, System.out, true)) {      System.exit(0);    }    try {      StringUtils.startupShutdownMessage(NameNode.class, argv, LOG);      NameNode namenode = createNameNode(argv, null);      if (namenode != null) {        namenode.join();      }    } catch (Throwable e) {      LOG.error("Failed to start namenode.", e);      terminate(1, e);    }  }

这段代码的重点在第8行,这里createNameNode方法创建了一个namenode对象,然后调用其join方法阻塞等待请求。

createNameNode方法的内容如下:

 public static NameNode createNameNode(String argv[], Configuration conf)      throws IOException {    LOG.info("createNameNode " + Arrays.asList(argv));    if (conf == null)      conf = new HdfsConfiguration();    // Parse out some generic args into Configuration.    GenericOptionsParser hParser = new GenericOptionsParser(conf, argv);    argv = hParser.getRemainingArgs();    // Parse the rest, NN specific args.    StartupOption startOpt = parseArguments(argv);    if (startOpt == null) {      printUsage(System.err);      return null;    }    setStartupOption(conf, startOpt);    switch (startOpt) {      case 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: {        NamenodeRole role = startOpt.toNodeRole();        DefaultMetricsSystem.initialize(role.toString().replace(" ", ""));        return new BackupNode(conf, role);      }      case RECOVER: {        NameNode.doRecovery(startOpt, conf);        return null;      }      case METADATAVERSION: {        printMetadataVersion(conf);        terminate(0);        return null; // avoid javac warning      }      case UPGRADEONLY: {        DefaultMetricsSystem.initialize("NameNode");        new NameNode(conf);        terminate(0);        return null;      }      default: {        DefaultMetricsSystem.initialize("NameNode");        return new NameNode(conf);      }    }  }

这段代码很简单。主要做的操作有三个:

  • 1、 创建配置文件对象

  • 2、 解析命令行的参数

  • 3、 根据参数执行对应方法(switch块)

其中创建的配置文件的为HdfsConfiguration(第5行),这里的HdfsConfiguration继承于Configuration类,它会加载hadoop的配置文件到内存中。然后解析传入main方法的参数,根据这个参数执行具体的方法。正常启动的时候执行的default里的内容。default的内容也很简单,就是创建一个Namenode对象。

这里先从HdfsConfiguration开始分析,详细讲解hdfs的配置文件处理。

首先看HdfsConfiguration的初始化方法如下:

  public HdfsConfiguration() {    super();  }

这里是调用其父类的初始化方法。

其父类为Configuration类,它的初始化方法如下:

  /** A new configuration. */  public Configuration() {    this(true);  }

这里可以看见他是调用了一个重载方法,传入了一个参数:true。

接着细看这个重载方法:

  public Configuration(boolean loadDefaults) {    this.loadDefaults = loadDefaults;    updatingResource = new ConcurrentHashMap();    synchronized(Configuration.class) {      REGISTRY.put(this, null);    }  }

这里也很简单,这里主要是为两个参数赋值,并将新创建的Configuration添加到REGISTRY中。
至此便创建好了一个配置文件。但是关于配置文件的初始化解析还未完成。在java里可以使用static关键字声明一段代码块,这段代码块在类加载的时候会被执行。在Configuration和HdfsConfiguration中都有静态代码块。
首先在Configuration类中,在第682行有一段静态代码块,其内容如下:

这段代码的重点在第695行和第696行,这里调用了一个addDefaultResource方法,这里传入了两个参数core-default.xml和core-site.xml。其中core-site.xml就是在安装hadoop的时候设置的配置文件。而core-default.xml是hadoop自带的配置文件,这个文件可以在hadoop的官方文档里查到,文档链接如下:https://hadoop.apache.org/docs/r2.7.6/hadoop-project-dist/hadoop-common/core-default.xml
同样在hadoop的源码里也有这个文件,它在hadoop-common-XX.jar中。

接着继续分析调用的addDefaultResource方法

其内容如下:

  public static synchronized void addDefaultResource(String name) {    if(!defaultResources.contains(name)) {      defaultResources.add(name);      for(Configuration conf : REGISTRY.keySet()) {        if(conf.loadDefaults) {          conf.reloadConfiguration();        }      }    }  }

这段代码也很简单。首先是第二行先从defaultResources中判断是否已经存在该配置文件,

这里的defaultResources是一个list

其定义如下:

 private static final CopyOnWriteArrayList defaultResources =    new CopyOnWriteArrayList();

若defaultResources中不存在这个配置文件,则继续向下执行,将这个配置文件添加到defaultResources中(第3行)。然后遍历REGISTRY中的key(第4行),这里的key就是在上文提到的Configuration对象。然后根据其loadDefaults的值来判断是否执行reloadConfiguration方法。
这里的loadDefaults的值就是上文分析的传入重载方法的值,上文传入的为true,所以其创建的Configuration对象在这里会执行reloadConfiguration方法。

reloadConfiguration方法内容如下:

  public synchronized void reloadConfiguration() {    properties = null;                            // trigger reload    finalParameters.clear();                      // clear site-limits  }

这里可以看见这个reloadConfiguration方法并没有真正的重新加载配置文件而是将properties的值设置为空。

同样在HdfsConfiguration也有类似的静态代码块,在第30行,其内容如下:

这里首先调用了一个addDeprecatedKeys方法然后调用了一个addDefaultResource。这里的addDefaultResource传了两个文件hdfs-default.xml和hdfs-site.xml。其中hdfs-site.xml是安装时的配置文件,hdfs-default.xml是其自带的默认文件,同上文的core-default.xml一样。官网链接为:https://hadoop.apache.org/docs/r2.7.6/hadoop-project-dist/hadoop-hdfs/hdfs-default.xml。文件位于:hadoop-hdfs-2.7.6.jar。

其中addDeprecatedKeys方法内容如下:

 private static void addDeprecatedKeys() {    Configuration.addDeprecations(new DeprecationDelta[] {      new DeprecationDelta("dfs.backup.address",        DFSConfigKeys.DFS_NAMENODE_BACKUP_ADDRESS_KEY),      new DeprecationDelta("dfs.backup.http.address",        DFSConfigKeys.DFS_NAMENODE_BACKUP_HTTP_ADDRESS_KEY),      new DeprecationDelta("dfs.balance.bandwidthPerSec",        DFSConfigKeys.DFS_DATANODE_BALANCE_BANDWIDTHPERSEC_KEY),      new DeprecationDelta("dfs.data.dir",        DFSConfigKeys.DFS_DATANODE_DATA_DIR_KEY),      new DeprecationDelta("dfs.http.address",        DFSConfigKeys.DFS_NAMENODE_HTTP_ADDRESS_KEY),      new DeprecationDelta("dfs.https.address",        DFSConfigKeys.DFS_NAMENODE_HTTPS_ADDRESS_KEY),      new DeprecationDelta("dfs.max.objects",        DFSConfigKeys.DFS_NAMENODE_MAX_OBJECTS_KEY),      new DeprecationDelta("dfs.name.dir",        DFSConfigKeys.DFS_NAMENODE_NAME_DIR_KEY),      new DeprecationDelta("dfs.name.dir.restore",        DFSConfigKeys.DFS_NAMENODE_NAME_DIR_RESTORE_KEY),      new DeprecationDelta("dfs.name.edits.dir",        DFSConfigKeys.DFS_NAMENODE_EDITS_DIR_KEY),      new DeprecationDelta("dfs.read.prefetch.size",        DFSConfigKeys.DFS_CLIENT_READ_PREFETCH_SIZE_KEY),      new DeprecationDelta("dfs.safemode.extension",        DFSConfigKeys.DFS_NAMENODE_SAFEMODE_EXTENSION_KEY),      new DeprecationDelta("dfs.safemode.threshold.pct",        DFSConfigKeys.DFS_NAMENODE_SAFEMODE_THRESHOLD_PCT_KEY),      new DeprecationDelta("dfs.secondary.http.address",        DFSConfigKeys.DFS_NAMENODE_SECONDARY_HTTP_ADDRESS_KEY),      new DeprecationDelta("dfs.socket.timeout",        DFSConfigKeys.DFS_CLIENT_SOCKET_TIMEOUT_KEY),      new DeprecationDelta("fs.checkpoint.dir",        DFSConfigKeys.DFS_NAMENODE_CHECKPOINT_DIR_KEY),      new DeprecationDelta("fs.checkpoint.edits.dir",        DFSConfigKeys.DFS_NAMENODE_CHECKPOINT_EDITS_DIR_KEY),      new DeprecationDelta("fs.checkpoint.period",        DFSConfigKeys.DFS_NAMENODE_CHECKPOINT_PERIOD_KEY),      new DeprecationDelta("heartbeat.recheck.interval",        DFSConfigKeys.DFS_NAMENODE_HEARTBEAT_RECHECK_INTERVAL_KEY),      new DeprecationDelta("dfs.https.client.keystore.resource",        DFSConfigKeys.DFS_CLIENT_HTTPS_KEYSTORE_RESOURCE_KEY),      new DeprecationDelta("dfs.https.need.client.auth",        DFSConfigKeys.DFS_CLIENT_HTTPS_NEED_AUTH_KEY),      new DeprecationDelta("slave.host.name",        DFSConfigKeys.DFS_DATANODE_HOST_NAME_KEY),      new DeprecationDelta("session.id",        DFSConfigKeys.DFS_METRICS_SESSION_ID_KEY),      new DeprecationDelta("dfs.access.time.precision",        DFSConfigKeys.DFS_NAMENODE_ACCESSTIME_PRECISION_KEY),      new DeprecationDelta("dfs.replication.considerLoad",        DFSConfigKeys.DFS_NAMENODE_REPLICATION_CONSIDERLOAD_KEY),      new DeprecationDelta("dfs.replication.interval",        DFSConfigKeys.DFS_NAMENODE_REPLICATION_INTERVAL_KEY),      new DeprecationDelta("dfs.replication.min",        DFSConfigKeys.DFS_NAMENODE_REPLICATION_MIN_KEY),      new DeprecationDelta("dfs.replication.pending.timeout.sec",        DFSConfigKeys.DFS_NAMENODE_REPLICATION_PENDING_TIMEOUT_SEC_KEY),      new DeprecationDelta("dfs.max-repl-streams",        DFSConfigKeys.DFS_NAMENODE_REPLICATION_MAX_STREAMS_KEY),      new DeprecationDelta("dfs.permissions",        DFSConfigKeys.DFS_PERMISSIONS_ENABLED_KEY),      new DeprecationDelta("dfs.permissions.supergroup",        DFSConfigKeys.DFS_PERMISSIONS_SUPERUSERGROUP_KEY),      new DeprecationDelta("dfs.write.packet.size",        DFSConfigKeys.DFS_CLIENT_WRITE_PACKET_SIZE_KEY),      new DeprecationDelta("dfs.block.size",        DFSConfigKeys.DFS_BLOCK_SIZE_KEY),      new DeprecationDelta("dfs.datanode.max.xcievers",        DFSConfigKeys.DFS_DATANODE_MAX_RECEIVER_THREADS_KEY),      new DeprecationDelta("io.bytes.per.checksum",        DFSConfigKeys.DFS_BYTES_PER_CHECKSUM_KEY),      new DeprecationDelta("dfs.federation.nameservices",        DFSConfigKeys.DFS_NAMESERVICES),      new DeprecationDelta("dfs.federation.nameservice.id",        DFSConfigKeys.DFS_NAMESERVICE_ID),      new DeprecationDelta("dfs.client.file-block-storage-locations.timeout",        DFSConfigKeys.DFS_CLIENT_FILE_BLOCK_STORAGE_LOCATIONS_TIMEOUT_MS),    });  }

这段代码很简单,只有一句话。调用了 Configuration的静态方法addDeprecations,并向其中传入了一个参数,参数类型为DeprecationDelta类的数组,并为数组中的数据进行赋值。

以上是"Hadoop之启动文件namenode原理的示例分析"这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注行业资讯频道!

0