知识点
相关文章
更多最近更新
更多HADOOP NAMENODE FORMAT过程分析
2019-03-28 13:23|来源: 网络
namenode format操作是使用Hadoop分布式文件系统前的步骤。如果不执行这个步骤,无法正确启动分布式文件系统。所以个人认为有必要对这个过程进行分析。
(1)启动format
hadoop namenode -format
在之前关于start-dfs.sh的脚本分析过程,已经介绍到hadoop的脚本,namenode对应的执行类是org.apache.hadoop.hdfs.server.namenode.NameNode类,传入的-format参数传入到执行类,作为执行类的参数。
(2)NameNode的入口main函数
try {
StringUtils.startupShutdownMessage(NameNode.class, argv, LOG);
NameNode namenode = createNameNode(argv, null); //通过createNameNode方法创建NameNode对象,并传入参数,这里传入的是-format
if (namenode != null)
namenode.join();
} catch (Throwable e) {
LOG.error(StringUtils.stringifyException(e));
System.exit(-1);
}
(3)NameNode.createNameNode创建NameNode实例
if (conf == null)
conf = new Configuration(); //创建Configuration实例,获取配置参数。
StartupOption startOpt = parseArguments(argv); //解析参数
if (startOpt == null) {
printUsage();
return null;
}
setStartupOption(conf, startOpt);
switch (startOpt) {
case FORMAT: //对应-format参数
boolean aborted = format(conf, true); //执行format()
System.exit(aborted ? 1 : 0); //执行后,直接退出,并不启动namenode服务
case FINALIZE:
aborted = finalize(conf, true);
System.exit(aborted ? 1 : 0);
default:
}
DefaultMetricsSystem.initialize("NameNode"); //如果不是-format和-finalize参数,则创建NameNode实例,启动namenode服务
NameNode namenode = new NameNode(conf);
return namenode;
(3)执行NameNode.format格式化hdfs操作
这个过程是整个format的流程的主要部分,里面设计到FSNamesystem和FSImage两个和hdfs文件系统关系密切的类。在这里并不展开说明,仅对其和format相关的操作进行分析
Collection<File> dirsToFormat = FSNamesystem.getNamespaceDirs(conf); //通过配置文件配置参数获取fsimage文件所存放的目录,本文后面的部分会单独介绍fsimage文件
Collection<File> editDirsToFormat =
FSNamesystem.getNamespaceEditsDirs(conf); //通过配置文件配置参数获取edits文件所存放的目录,本文后面的部分会单独介绍edits文件
//下面的for循环,用于验证fsimage存放的目录,如果已存在,需要用户确认是否要格式化,如果不允许格式化,则退出。
for(Iterator<File> it = dirsToFormat.iterator(); it.hasNext();) {
File curDir = it.next();
if (!curDir.exists())
continue;
if (isConfirmationNeeded) {
System.err.print("Re-format filesystem in " + curDir +" ? (Y or N) ");
if (!(System.in.read() == 'Y')) {
System.err.println("Format aborted in "+ curDir);
return true;
}
while(System.in.read() != '\n'); // discard the enter-key
}
}
//这里分两个步骤,一个是new FSImage,一个是new FSNamesystem.
//new FSImage调用了FSImage的setStorageDirectories方法,将fsimage和edits目录都存放在StorageDirectory列表storageDirs中
//并且每个StorageDirectory以NameNodeDirType为IMAGE_AND_EDITS、IMAGE、EDITS来区分。
//new FSNamesystem创建了HDFS文件系统的根目录FSDirectory对象dir和DelegationTokenSecretManager对象dtSecretManager(这个还不明白是做什么用的)。
FSNamesystem nsys = new FSNamesystem(new FSImage(dirsToFormat,
editDirsToFormat), conf);
//最后,就是调用FSImage对象来完成format操作了,这也是整个文件系统格式化的核心过程。
nsys.dir.fsImage.format();
(4)FSImage.format
//初始化系统的基本信息,包括版本信息,文件系统的编号等
this.layoutVersion = FSConstants.LAYOUT_VERSION;
this.namespaceID = newNamespaceID();
this.cTime = 0L;
this.checkpointTime = FSNamesystem.now();
//这个for循环,就是对之前提到的storageDirs列表的遍历,对每个StorageDirectory对象进行format操作
for (Iterator<StorageDirectory> it =
dirIterator(); it.hasNext();) {
StorageDirectory sd = it.next();
//这个功能较简单,主要分两个步骤
//调用clearDirectory完全删除sd所在的目录,然后再创建空目录
//调用saveCurrent创建sd目录下的current目录和fsimage目录及相关文件。具体的创建过程就不分析了,下面的部分就对name目录结构进行分析
format(sd);
}
(5)saveCurrent(sd)过程分析
File curDir = sd.getCurrentDir(); //获取sd目录下的current目录
NameNodeDirType dirType = (NameNodeDirType)sd.getStorageDirType(); //读取目录类型,前面说过,有三种
// save new image or new edits
if (!curDir.exists() && !curDir.mkdir())
throw new IOException("Cannot create directory " + curDir);
if (dirType.isOfType(NameNodeDirType.IMAGE)) //如果是image或imageandedit类型,创建fsimage文件,并写入根目录信息
saveFSImage(getImageFile(sd, NameNodeFile.IMAGE));
if (dirType.isOfType(NameNodeDirType.EDITS))
editLog.createEditLogFile(getImageFile(sd, NameNodeFile.EDITS)); //如果是edit或imageandedit类型,创建edits文件,并写入版本信息
// write version and time files
sd.write(); //写入支持旧版本的fsimage目录内容、写入版本信息到VERSION文件中、写入当前系统时间到fstime目录中
(6)name目录结构分析
相关问答
更多-
很酷,我找到了解决方案。 停止所有运行的服务器 1) stop-all.sh 编辑文件/usr/local/hadoop/conf/hdfs-site.xml并添加下面的配置(如果缺失)
dfs.data.dir /app/hadoop/tmp/dfs/name/data true d ... -
Hadoop namenode -format Hadoop namenode目录包含fsimage和编辑文件,其中包含有关hadoop文件系统的基本信息,例如数据可用位置,用户创建的文件 如果格式化namenode,那么以上信息将从hdfs-site.xml中指定的namenode目录中删除为dfs.namenode.name.dir 但是你仍然拥有hadoop的数据,但不包含namenode元数据 Hadoop namenode -format Hadoop namenode directory con ...
-
这不是一个错误。 在启动HDFS之前,您需要格式化namenode。 这与运行Linux / Windows之前需要格式化磁盘相似。 This is not an error. Before you can start HDFS, you need to format the namenode. This is similar to before you can run Linux/Windows you need to format the disk.
-
它没有从导出的变量中获取类名。 您可以尝试从脚本中注释掉这一行并尝试: export HADOOP_OPTS=”-Djava.security.krb5.realm= -Djava.security.krb5.kdc=” Its not getting the class name from the exported variable. You can try commenting out this line from the script and try: export HADOOP_OPTS=”-Dj ...
-
Namenode没有运行(Namenode not running)[2023-07-12]
这很简单 - 格式化你的名字节点 mcbatyuk:hadoop bam$ bin/hadoop namenode -format Warning: $HADOOP_HOME is deprecated. 12/04/11 21:04:55 INFO namenode.NameNode: STARTUP_MSG: /************************************************************ STARTUP_MSG: Starting NameNode STA ... -
你必须将hadoop-hdfs-2.7.0.jar添加到你的hadoop类路径中。 只需在$ HADOOP_HOME / etc / hadoop / hadoop-env.sh中添加以下行: export HADOOP_HOME=/path/to/hadoop export HADOOP_CLASSPATH=$HADOOP_CLASSPATH:$HADOOP_HOME/share/hadoop/hdfs/hadoop-hdfs-2.7.0.jar 现在,停止所有hadoop进程。 尝试现在格式化name ...
-
最重要的是名称节点中的META数据。 数据节点可能具有副本形式的数据副本。 但是如果删除或更改了namenode .META,那么数据应该丢失,因为它是格式化命令。 The most important thing is the META data in your name node. Data nodes might have a copy of the data in the form of replicas. But If the namenode .META is deleted or altere ...
-
这取决于您所讨论的Hadoop版本。 在Hadoop 2之前, Namenode是一个单点故障,所以如果它失败意味着你的集群变得无法使用。 在这种情况下,即使SecondaryNameNode也没有帮助,因为它仅用于检查点,而不是用作NameNode的备份。 当NameNode失败时,像管理员这样的人必须手动重启NameNode 。 但是从Hadoop 2开始,你有更好的方法来处理NameNode失败。 您可以并排运行2个冗余NameNodes ,这样,如果其中一个Namenodes失败,群集将快速故障转移 ...
-
您在hadoop-env.sh中错误地设置了JAVA_HOME。 给出java_home的绝对路径。你可以使用下面的命令找出java当前的java路径: alternatives --config java 它将提供您已安装的所有Java版本并选择正确的版本并将此java路径设置为hadoop-env.sh,如下所示: export JAVA_HOME=/usr/java/jdk1.*/bin 另一种方法是将$ JAVA_HOME设置为用户的.bashrc。 所以不需要设置为hadoop-env.sh ...
-
谢谢你的建议。 事实证明它是一个blooper,我只放了两个/而不是文件中给出的三个URI。 它现在有效! thanks for the suggestions. It turned out to be a blooper, I have put only two /'s instead of three as given in the document for the URI. It works now !