HDFS源码解析(一)

来源:互联网 发布:永恒纪元戒官网通知 编辑:程序博客网 时间:2024/05/01 05:36

废话不多说,直接进入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);    }  }

DFSUtil的parseHelpArgument方法用于解析输入的命令行参数。接下来看try,catch语句块:

StringUtils的startupShutdownMessage方法字面很容易看出是打印启动关闭信息;NameNode

的主要工作由createNameNode方法完成,我们进入createNameNode可以发现主要是switch语句块,我们重点看下关于格式化format

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

然后进入format方法,每一步的注释写在代码后面,自己看

private static boolean format(Configuration conf, boolean force,      boolean isInteractive) throws IOException {    String nsId = DFSUtil.getNamenodeNameServiceId(conf); // 获取nameserviceid,在hadoop ha中配置    String namenodeId = HAUtil.getNameNodeId(conf, nsId); // 获取namenodeid,    initializeGenericKeys(conf, nsId, namenodeId);    checkAllowFormat(conf); // 判断是否允许格式化,也就是你不能把正在运行的hdfs给格了    if (UserGroupInformation.isSecurityEnabled()) { // 看到UserGroupInformation,我们知道这是hdfs系统权限相关的,                                                    // 判断是否使用Kerberos验证      InetSocketAddress socAddr = getAddress(conf);      SecurityUtil.login(conf, DFS_NAMENODE_KEYTAB_FILE_KEY,          DFS_NAMENODE_USER_NAME_KEY, socAddr.getHostName());    }    /*    获取hdfs-site.xml中dfs.namenode.name.dir设置的路径,如/home/hadoop/dfs/name    用于存储文件系统命名空间镜像     */    Collection<URI> nameDirsToFormat = FSNamesystem.getNamespaceDirs(conf);    /*    获取hdfs-site.xml中dfs.namenode.shared.edits.dir设置的路径,如果使用的hadoop的ha配置,    那么值可以为qjournal://node1:8485;node2:8485;node3:8485/clusterid,其中clusterid是dfs.nameservices配置的值     */    List<URI> sharedDirs = FSNamesystem.getSharedEditsDirs(conf);    List<URI> dirsToPrompt = new ArrayList<URI>();    dirsToPrompt.addAll(nameDirsToFormat);    dirsToPrompt.addAll(sharedDirs);    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 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);    } catch (IOException ioe) {      LOG.warn("Encountered exception during format: ", ioe);      fsImage.close();      throw ioe;    }    return false;  }

回到NameNode的main方法,namenode.join最终启动的是RPC.Server serviceRpcServer,RPC.ServerclientRpcServer两大线程。

serviceRpcServer监听来自DataNodes的请求,clientRpcServer监听来自客户端的请求。













0 0