Hadoop学习笔记(六)

接着继续上一篇关于FORMAT的分析——

 

(3)对内存镜像中数据结构的初始化:

初始化工作主要由FSImage的format函数完成,对象主要是FSImage的成员变量:

layoutVersion  ---当前软件所处的版本

namespaceID  ---HDFS的身份标识,唯一

cTime      ---FSImage创建时间

checkpointTime   ---Namenode第一次checkpoint的时间

 

在将成员变量初始化后,会遍历所有的元数据存储目录(在上一步中,已经把备份目录存放到了StorageDIr供这一步使用),一次调用format函数的重载函数,对其进行格式化

  public void format() throws IOException {

  ...

  for (Iterator<StorageDirectory> it = dirIterator();it.hasNext();) {

  StorageDirectory sd = it.next();

  format(sd);

}

}

 

(4)将内存镜像写入元数据备份目录:

大致分析一下代码的结构————

① 首先是接着上面的format()函数:

  这里主要就是那个saveCurrent(sd)函数,用于把当前格式化后的内存镜像保存到sd对象对应的目录中去。

package org.apache.hadoop.hdfs.server.namenode;

FSImage.java

void format(StorageDirectory sd) throws IOException {

  sd.clearDirectory();

  sd.lock();

  try{

    saveCurrent(sd);

}

  finally{

    sd.unlock();

}

  ....

}

 

 

② saveCurrent函数:

其中主要是两个if 判断,如果是fsimage就调用saveFSImage,如果是editslog就调用createEditLogFile在sd指定的目录下创建对应的目录或文件。

protected void saveCurrent(StorageDirectory sd) throws IOException {

  File curDIr = sd.getCurrentDir();

  ....

  if (dirType.isOfType(NameNOdeDirType.IMAGE))

    saveFSImage(getImageFile(sd,NameNodeFile.IMAGE));

  if (dirType.isOfType(NameNOdeDirType.EDITS))

    editLog.createEditLogFile(getImageFile(sd,NameNodeFile.EDITS));

  sd.write();

}

 

③ saveFSImage()函数:

先把一些基本信息写入到对应目录下

然后保存当前内存镜像对应根目录下的内容,这个根目录就是之前在FSDirectory构造函数中创建的那个HDFS的rootDir

然后保存根目录下其他的Inode信息

void saveFSImage(File newFile) throws IOException {

  ...

  saveINode2Image(strbuf,fsDir.rootDir,out);

  saveImage(strbuf,0,fsDIr.rootDir,out);

  ...

}

 

④ saveINode2Image()函数:

用来保存Inode的信息,根据该Inode是目录,链接或者文件作出对应的保存动作

private static void saveINode2Image(ByteBuffer name,INode node,DataOutputStream out)  throws IOException{

  ...

  if (node.isDirectory()) {...}

  else if (node.isLink()) {...}

  else {

    INodeFile fileINode = (INodeFile) node;

    ...

    }

}

 

⑤ saveImage()函数:

判断该Inode是否有子目录或文件,如果没有,结束;

如果有,则获取所有子目录和文件,调用saveInode2Image()来保存对应内容;对应下面代码第一个for循环

如果子INOde中有的是目录,则调用saveImage()函数处理,也就是再一次进入该目录,保存所有INode内容,然后查看是否有子目录;对应第二个for循环

private static void saveImage(ByteBuffer parentPrefix,int prefixLength,INodeDirectory current,DataOutputStream out) throws IOException {

  ...

  if (current.getChildrenRaw() == null)  return;

  for (INode child:current.getChildren()) {

    ...

    saveINode2Image(parentPrefix,child,out);

}

  for (INode child : current.getChildren()) {

    if (!child.isDirectory()) continue;

    ..

    saveImage(parentPrefix,newPrefixLength,(INodeDirectory)child,out);

}

}

 

 当fsimage和editlog写入后,准备写入fstime和VERSION——

⑥ write()函数:

format在写入FSImage文件或Edits文件成功后,调用类StorageDirectory的write方法写入fstime和VERSION文件,类StorageDirectory是类Storage的内部成员类,可以访问其所声明的变量和方法。

write首先将类Storage自身属性信息(layoutVersion,storageType,namespaceID,cTime)写入类Properties的实例对象pros中

通过类FSImage重载setFIelds方法写入fstime文件

实例化类RandomAccessFile的对象File,用于对VERSION文件的操作,最后通过file写入属性信息并更新VERSION文件长度

 

public abstract class Storage extends StorageInfo {

  ...

  public class StorageDirectory {

    ...

    public File getVersionFile() {...}

    public void write() thorws IOException {

      ...

      write(getVersionFile());

    }

    public void write(File to) throws IOException {

       Properties props = new Properties();

       setFileds(props,this);        //注意这里是使用类FSImage重载的父类Storage的setFileds方法,因为在上面实际调用write的sd.write();

       RandomAccessFile file = new RandomAccessFile(to,"rws");

      ...

    }    

  }

  protected void setFields (Properties props,StorageDirectory sd) throws IOException {

      props.setProperty("layoutVersion",String.valueOf(layoutVersion));

      props.setProperty("storageType",storageType.toString());

      props.setProperty("namespaceID",String.valueOf(namespaceID));

      props.setProperty("cTime",String.valueOf(cTime));

}

  

}

 

类FSImage重载父类的setFileds方法,在其方法中,将checkpointTime写入fstime文件

⑦ setFileds()函数:

protected void setFields (Properties props,StorageDirectory sd) throws IOException {

  super.setFields(props,sd);

  ...

  writeCheckpointTime(sd);

}

 

 

posted on 2012-08-30 10:47  melburg  阅读(166)  评论(0)    收藏  举报