阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

Hadoop-2.4.1学习之NameNode -format源码分析

205次阅读
没有评论

共计 7836 个字符,预计需要花费 20 分钟才能阅读完成。

在 Hadoop-2.X 中,使用 hdfs namenode –format 对文件系统进行格式化。虽然无论是在生产环境还是测试环境中,已经使用了该命令若干次了,也大体了解该命令就是在本地文件系统中创建几个文件夹,但具体是如何执行的则需要通过阅读源代码来了解了。

要想看到该命令的源代码,需要看看 hdfs 脚本中是如何执行相应的 java 类的。在 hdfs 脚本中,下面的语句说明了实际执行的 java 类和参数,其中类为 org.apache.hadoop.hdfs.server.namenode.NameNode,参数为 -format。虽然在命令行中输入的为 hdfs namenode –forma,但将 namenode 赋予了 COMMAND,并进行了参数的移位,这样参数就剩下了 -format。

————————————– 分割线 ————————————–

Ubuntu 13.04 上搭建 Hadoop 环境 http://www.linuxidc.com/Linux/2013-06/86106.htm

Ubuntu 12.10 +Hadoop 1.2.1 版本集群配置 http://www.linuxidc.com/Linux/2013-09/90600.htm

Ubuntu 上搭建 Hadoop 环境(单机模式 + 伪分布模式)http://www.linuxidc.com/Linux/2013-01/77681.htm

Ubuntu 下 Hadoop 环境的配置 http://www.linuxidc.com/Linux/2012-11/74539.htm

单机版搭建 Hadoop 环境图文教程详解 http://www.linuxidc.com/Linux/2012-02/53927.htm

搭建 Hadoop 环境(在 Winodws 环境下用虚拟机虚拟两个 Ubuntu 系统进行搭建)http://www.linuxidc.com/Linux/2011-12/48894.htm

————————————– 分割线 ————————————–

COMMAND=$1
Shift

if [“$COMMAND” = “namenode”] ; then
  CLASS=’org.apache.hadoop.hdfs.server.namenode.NameNode’
  HADOOP_OPTS=”$HADOOP_OPTS $HADOOP_NAMENODE_OPTS”

exec “$JAVA” -Dproc_$COMMAND $JAVA_HEAP_MAX $HADOOP_OPTS $CLASS “$@”

在 eclipse 中找到 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.fatal(“Exception in namenode join”, e);
      terminate(1, e);
    }
  }

其中 parseHelpArgument 方法用于解析命令行参数,startupShutdownMessage 方法输出启动和关闭的信息,NameNode 的主要工作由 createNameNode 方法完成。在 createNameNode 中执行 format 方法之前先对参数进行了解析,具体代码如下,其中 argv 根据 format 时使用的参数可以为:-format [-clusterid cid] [-force] [-nonInteractive](完整的命令为 hdfs namenode [-format [-clusterid cid] [-force] [-nonInteractive]])。该方法用于设置 StartupOption 中的 clusterId 为 cid,若使用了 -force 参数则 StartupOption 中的 isForceFormat 为 true,若使用了 -nonInteractive 则将 StartupOption 中的 isInteractiveFormat 为 false,后两个参数的默认值为 false 和 true。

StartupOption startOpt = parseArguments(argv);

在 createNameNode 方法中与 -format 有关系的代码如下,且在执行完毕后返回 null,结合 main 方法中的代码可以得知,HDFS 的 format 执行完毕。format 方法的参数分别为 HdfsConfiguration、isForceFormat 和 isInteractiveFormat。

case FORMAT: {
        boolean aborted = format(conf, startOpt.getForceFormat(),
            startOpt.getInteractiveFormat());
        terminate(aborted ? 1 : 0);
        return null; // avoid javac warning
      }

接下来进入 format 方法,看看具体都执行了哪些操作,由于该方法是整个 HDFS 格式化的核心方法,所以会完整细致的分析该方法,这样势必会将整个方法分成几个部分,下面是第一部分的代码,这部分代码用于获取 NameNode 的 NameServiceID 和 NameNode ID,并检查 NameNode 是否允许格式化,其中使用了参数 dfs.namenode.support.allow.format,该参数的默认值为 true(在生产环境中可以在格式化完成后将该参数设置为 false,避免格式化正在运行的 HDFS)。

String nsId = DFSUtil.getNamenodeNameServiceId(conf);
    String namenodeId = HAUtil.getNameNodeId(conf, nsId);
    initializeGenericKeys(conf, nsId, namenodeId);
    checkAllowFormat(conf);

    if (UserGroupInformation.isSecurityEnabled()) {
      InetSocketAddress socAddr = getAddress(conf);
      SecurityUtil.login(conf, DFS_NAMENODE_KEYTAB_FILE_KEY,
          DFS_NAMENODE_USER_NAME_KEY, socAddr.getHostName());
    }

更多详情见请继续阅读下一页的精彩内容 :http://www.linuxidc.com/Linux/2014-09/107140p2.htm

第二部分代码如下,主要根据配置文件获取要格式化的目录、存储 edits 日志的目录等,以及在未指定 clusterId 的情况生成新的 clusterId 用于标识命名空间。

/* 获取参数 dfs.namenode.name.dir 设置的目录,该值用于存储 fsimage
    * 默认值为 file://${Hadoop.tmp.dir}/dfs/name,
    * 其中 hadoop.tmp.dir 定义在 core-default.xml 中,值为 /tmp/hadoop-${user.name}
 */
Collection<URI> nameDirsToFormat = FSNamesystem.getNamespaceDirs(conf);
/* 获取在 primary 和 secondary namenode 之间共享的 edits 目录
* 相应的参数为 dfs.namenode.shared.edits.dir
 */
    List<URI> sharedDirs = FSNamesystem.getSharedEditsDirs(conf);
    List<URI> dirsToPrompt = new ArrayList<URI>();
    dirsToPrompt.addAll(nameDirsToFormat);
dirsToPrompt.addAll(sharedDirs);
/* 获取保存 edits 的目录,对应的参数为 dfs.namenode.edits.dir
* 若上面的参数没有配置,则使用与 fsimage 一致的目录
*/
    List<URI> editDirsToFormat = FSNamesystem.getNamespaceEditsDirs(conf);

    // if clusterID is not provided – see if you can find the current one
    String clusterId = StartupOption.FORMAT.getClusterId();
    if(clusterId == null || clusterId.equals(“”)) {
      //Generate a new cluster id
      clusterId = NNStorage.newClusterID();
    }
    System.out.println(“Formatting using clusterid: ” + clusterId);

最后一部分代码执行了创建 fsimage 和 edits 文件的工作,由于这两个文件的创建可以做为单独的源码分析进行,在此就不进行详细地分析,会有专门的文章学习这部分代码。

FSImage fsImage = new FSImage(conf, nameDirsToFormat, editDirsToFormat);
    try {
      FSNamesystem fsn = new FSNamesystem(conf, fsImage);
      fsImage.getEditLog().initJournalsForWrite();

      if (!fsImage.confirmFormat(force, isInteractive)) {
        return true; // aborted
      }
      fsImage.format(fsn, clusterId);

现在已经分析完了执行 hdfs namenode –format 命令时都执行了哪些操作,其实就是根据配置文件中的特定参数如 dfs.namenode.name.dir 等,将 fsimage 和 edits 文件写入这些目录,而 fsimage 和 edits 文件的创建及格式等分析见:http://www.linuxidc.com/Linux/2014-09/107139.htm。

更多 Hadoop 相关信息见 Hadoop 专题页面 http://www.linuxidc.com/topicnews.aspx?tid=13

在 Hadoop-2.X 中,使用 hdfs namenode –format 对文件系统进行格式化。虽然无论是在生产环境还是测试环境中,已经使用了该命令若干次了,也大体了解该命令就是在本地文件系统中创建几个文件夹,但具体是如何执行的则需要通过阅读源代码来了解了。

要想看到该命令的源代码,需要看看 hdfs 脚本中是如何执行相应的 java 类的。在 hdfs 脚本中,下面的语句说明了实际执行的 java 类和参数,其中类为 org.apache.hadoop.hdfs.server.namenode.NameNode,参数为 -format。虽然在命令行中输入的为 hdfs namenode –forma,但将 namenode 赋予了 COMMAND,并进行了参数的移位,这样参数就剩下了 -format。

————————————– 分割线 ————————————–

Ubuntu 13.04 上搭建 Hadoop 环境 http://www.linuxidc.com/Linux/2013-06/86106.htm

Ubuntu 12.10 +Hadoop 1.2.1 版本集群配置 http://www.linuxidc.com/Linux/2013-09/90600.htm

Ubuntu 上搭建 Hadoop 环境(单机模式 + 伪分布模式)http://www.linuxidc.com/Linux/2013-01/77681.htm

Ubuntu 下 Hadoop 环境的配置 http://www.linuxidc.com/Linux/2012-11/74539.htm

单机版搭建 Hadoop 环境图文教程详解 http://www.linuxidc.com/Linux/2012-02/53927.htm

搭建 Hadoop 环境(在 Winodws 环境下用虚拟机虚拟两个 Ubuntu 系统进行搭建)http://www.linuxidc.com/Linux/2011-12/48894.htm

————————————– 分割线 ————————————–

COMMAND=$1
Shift

if [“$COMMAND” = “namenode”] ; then
  CLASS=’org.apache.hadoop.hdfs.server.namenode.NameNode’
  HADOOP_OPTS=”$HADOOP_OPTS $HADOOP_NAMENODE_OPTS”

exec “$JAVA” -Dproc_$COMMAND $JAVA_HEAP_MAX $HADOOP_OPTS $CLASS “$@”

在 eclipse 中找到 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.fatal(“Exception in namenode join”, e);
      terminate(1, e);
    }
  }

其中 parseHelpArgument 方法用于解析命令行参数,startupShutdownMessage 方法输出启动和关闭的信息,NameNode 的主要工作由 createNameNode 方法完成。在 createNameNode 中执行 format 方法之前先对参数进行了解析,具体代码如下,其中 argv 根据 format 时使用的参数可以为:-format [-clusterid cid] [-force] [-nonInteractive](完整的命令为 hdfs namenode [-format [-clusterid cid] [-force] [-nonInteractive]])。该方法用于设置 StartupOption 中的 clusterId 为 cid,若使用了 -force 参数则 StartupOption 中的 isForceFormat 为 true,若使用了 -nonInteractive 则将 StartupOption 中的 isInteractiveFormat 为 false,后两个参数的默认值为 false 和 true。

StartupOption startOpt = parseArguments(argv);

在 createNameNode 方法中与 -format 有关系的代码如下,且在执行完毕后返回 null,结合 main 方法中的代码可以得知,HDFS 的 format 执行完毕。format 方法的参数分别为 HdfsConfiguration、isForceFormat 和 isInteractiveFormat。

case FORMAT: {
        boolean aborted = format(conf, startOpt.getForceFormat(),
            startOpt.getInteractiveFormat());
        terminate(aborted ? 1 : 0);
        return null; // avoid javac warning
      }

接下来进入 format 方法,看看具体都执行了哪些操作,由于该方法是整个 HDFS 格式化的核心方法,所以会完整细致的分析该方法,这样势必会将整个方法分成几个部分,下面是第一部分的代码,这部分代码用于获取 NameNode 的 NameServiceID 和 NameNode ID,并检查 NameNode 是否允许格式化,其中使用了参数 dfs.namenode.support.allow.format,该参数的默认值为 true(在生产环境中可以在格式化完成后将该参数设置为 false,避免格式化正在运行的 HDFS)。

String nsId = DFSUtil.getNamenodeNameServiceId(conf);
    String namenodeId = HAUtil.getNameNodeId(conf, nsId);
    initializeGenericKeys(conf, nsId, namenodeId);
    checkAllowFormat(conf);

    if (UserGroupInformation.isSecurityEnabled()) {
      InetSocketAddress socAddr = getAddress(conf);
      SecurityUtil.login(conf, DFS_NAMENODE_KEYTAB_FILE_KEY,
          DFS_NAMENODE_USER_NAME_KEY, socAddr.getHostName());
    }

更多详情见请继续阅读下一页的精彩内容 :http://www.linuxidc.com/Linux/2014-09/107140p2.htm

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-20发表,共计7836字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中