【框架解析】Hadoop系统分析(三)--namenode format

12 篇文章 0 订阅

hadoop namenode后需要带上一系列参数才能顺利执行。执行hadoop namenode时,会从org.apache.hadoop.hdfs.server.namenode.NameNode进入hadoop,通过参数的不同调用不同的方法对namenode进行操作。

try {
 StringUtils.startupShutdownMessage(NameNode.class, argv, LOG);
 NameNode namenode = createNameNode(argv, null);
 if (namenode \!= null)
   namenode.join();
} catch (Throwable e) {
 LOG.error(StringUtils.stringifyException(e));
 System.exit(-1);
}

hadoop namenode -format

格式化namenode。在安装好一个新的空白的hadoop后,需要对hdfs进行格式化,生成干净的元数据。format以后,才能进行后续的动作将空白的hadoop集群启动。
主要生成以下几个文件:
文件名作用
dfs.name.dir/current/fsimagehdfs中文件的元数据信息,启动时候会和edits文件合并后加载到内存,构成完整的元数据信息
dfs.name.dir/current/VERSION当前hadoop集群的版本信息,NamespaceId等
dfs.name.dir/image/fsimage阻止早期版本使用这个fsimage启动(0.13以前)
dfs.name.edits.dir/current/edits保存对元数据进行的每次操作,比如创建文件,删除 文件。类似于mysql中的binlog机制。

NameNode.createNameNode是会判断是否是format,具体的源码执行过程如下:

case FORMAT:
        boolean aborted = format(conf, true);
        System.exit(aborted ? 1 : 0);

进入format方法后,会读取到配置项中配置的dfs.name.dir目录和dfs.name.edits.dir目录。
dfs.name.dir用于保存hadoop集群的元数据信息
dfs.name.edits.dir用于保存NameNode的editlog,记录对hdfs的每一步操作。
Collection<File> dirsToFormat = FSNamesystem.getNamespaceDirs(conf);
Collection<File> editDirsToFormat = FSNamesystem.getNamespaceEditsDirs(conf);
之后执行格式化的操作

FSNamesystem nsys = new FSNamesystem(new FSImage(dirsToFormat,editDirsToFormat), conf);
nsys.dir.fsImage.format();

format()操作会调用FsImage.format(StorageDirectory sd)方法,循环处理每个目录。在format中:

sd.clearDirectory(); // 删除目录中的current目录,并重新创建current目录
sd.lock();
try {
  saveCurrent(sd);//往current目录中写入内容
} finally {
  sd.unlock();
}

根据目录类型来调用不同的写入文件方法,IMAGE目录:
FSImage.saveFSImage(getImageFile(sd, NameNodeFile.IMAGE));

往current/fsimage中写入如下信息:

out.writeInt(FSConstants.LAYOUT_VERSION);  //版本信息
      out.writeInt(namespaceID);//namespaceid,每次调用format()方法是生成的随机数
      out.writeLong(fsDir.rootDir.numItemsInTree());//系统中所有文件数
      out.writeLong(fsNamesys.getGenerationStamp());//生成时间戳
      byte[] byteStore = new byte[4*FSConstants.MAX_PATH_LENGTH];
      ByteBuffer strbuf = ByteBuffer.wrap(byteStore);
      // save the root
      saveINode2Image(strbuf, fsDir.rootDir, out);//保存根节点的相关信息,如replication数量,修改时间,访问时间,块数,权限状态等等。
      // save the rest of the nodes
      saveImage(strbuf, 0, fsDir.rootDir, out);//保存子节点的相关信息,这是个递归过程,会把节点的整个子树都遍历一遍
      fsNamesys.saveFilesUnderConstruction(out);//写入现在与租约关联的block的相关信息
      fsNamesys.saveSecretManagerState(out);
写完后fsimage的数据格式如下图:


EDITS目录:

FSEditLog.createEditLogFile(getImageFile(sd, NameNodeFile.EDITS));//创建current/edits文件

最后调用Storage.write()写入版本信息相关内容

corruptPreUpgradeStorage(root);//创建$DATA/name/image/fsimage作为废弃文件让hadoop 0.13之前的版本不能够使用这个目录来启动
write(getVersionFile());  //编写current/VERSION文件

这些数据文件都创建完成后,一个空白的hadoop就能够在下一步正常启动了

整个format的大致流程如下:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值