当前位置:编程学习 > JAVA >>

HDFS1.0源代码解析—DataNode端数据存储和管理DataStorage和FSDataset解析

本部分主要介绍DN中的数据的存储和管理,我们知道从逻辑上来看我们把数据存储到HDFS这个文件系统中,但是具体数据在每个DN上是如何存储的呢,这其中就牵扯到几个比较大的类DataStorage、Storage、FSDataset等等。一开始读DN源代码这部分就搞得不是很清楚,现在理一下思路,也算给刚开始看得童鞋一些提示。
在配置hdfs-site.xml的时候我们会配置这样一个选项
[java] 
16     <property> 
17         <name>dfs.data.dir</name> 
这个配置项就是每个DN具体存储数据的位置,存储目录底下文件有以下几类:
blocksBeingWritten  current  detach  storage  tmp
其中blocksBeingWritten  是当前正在写的block,写完会从blocksBeingWritten  转移到current文件底下,current是保存当前已经写入的数据,也就是数据存储的主目录。detach  是硬链接,主要用于写时拷贝。tmp存储一些临时信息,在DN启动检查时会将tmp中的数据删除。
首先来看DataStorage,它在DN数据管理中起着怎么样的作用。
[java]
public class DataStorage extends Storage {    
从DataStorage类的声明可以看出DataStorage是用于DN数据管理的Storage的特殊类,那么很容易就会想到NN中也有一个这样的特殊类(是的,FSImage),torage类的主要作用就是存储两者公共的一些信息。
我们来看一下在DN启动时,DataStorage起到了什么样的作用。
[java] 
311   void startDataNode(Configuration conf, 
312                      AbstractList<File> dataDirs, SecureResources resources 
313                      ) throws IOException { 
 
343     storage = new DataStorage(); 
 
380       storage.recoverTransitionRead(nsInfo, dataDirs, startOpt); 
上边的几行代码实在方法startDataNode中主要与DataStorage交互的代码。首先还是来看DataStorage的初始化,
[java] 
59   DataStorage() { 
60     super(NodeType.DATA_NODE); 
61     storageID = ""; 
62   } 
主要工作还是声明自己存储的类型。下面接着看recoverTransitionRead方法,核心代码如下:
[java]
106     for(Iterator<File> it = dataDirs.iterator(); it.hasNext();) { 
107       File dataDir = it.next(); 
108       StorageDirectory sd = new StorageDirectory(dataDir);//初始化storage中的root 
109       StorageState curState; 
110       try { 
111         curState = sd.analyzeStorage(startOpt); 
112         // sd is locked but not opened 
113         switch(curState) { 
114         case NORMAL: 
115           break; 
116         case NON_EXISTENT: 
117           // ignore this storage 
118           LOG.info("Storage directory " + dataDir + " does not exist."); 
119           it.remove(); 
120           continue; 
121         case NOT_FORMATTED: // format 
122           LOG.info("Storage directory " + dataDir + " is not formatted."); 
123           LOG.info("Formatting ..."); 
124           format(sd, nsInfo); 
125           break; 
126         default:  // recovery part is common 
127           sd.doRecover(curState); 
128         } 
首选看到这个循环是对hdfs-site.xml这个配置文件中,配置的每个存储路径进行检查。具体检查的通过StorageDirectory的analyzeStorage方法进行,该方法会返回当前存储处于何种状态(这个状态在前边的博客中已经讲述,主要是升级过程可能造成DN处于多种状态)。如果是NORMAL说明一切正常,不作处理;如果是NON_EXISTENT说明配置项中的这个目录不存在;如果是NOT_FORMATTED,说明命令是进行格式化的操作(hadoop dfs -format),通过 format(sd, nsInfo); 方法格式化;其他状态通过sd.doRecover(curState)方法,进行处理。
通过上面的描述很容易发现StorageDirectory的对象,在处理的各个部分都起着关键作用。那么来分析下这个StorageDirectory类的主要作用,StorageDirectory是DataStorage父类Storage中的一个内部类
[java] 
182   public class StorageDirectory { 
183     File              root; // root directory 
184     FileLock          lock; // storage lock 
185     StorageDirType dirType; // storage dir type 
主要的成员变量有3个,我们重点关注的是root,在初始化它被初始化为配置的存储路径中的某一个。下面分析其中的主要方法,先来看我们用到的analyzeStorage方法,这部分代码比较长,就不在贴了,简单的介绍下其中的逻辑。首先判断root这个路径是否已经存在,如果不存在并且目前执行的是StartupOption.FORMAT格式化命令的话,返回StorageState.NON_EXISTENT。在判断root是否是目录或者是否可写,如果有一个不满足返回StorageState.NON_EXISTENT。如果配置的路径存在,首先对文件进行加锁,对文件加锁的一个常用技巧就是建立一个空的filelock文件,将所加在这个空白文件上,通过对这个文件的加锁控制一个目录的同步行为。
[java] 
469       boolean hasPrevious = getPreviousDir().exists(); 
470       boolean hasPreviousTmp = getPreviousTmp().exists(); 
471       boolean hasRemovedTmp = getRemovedTmp().exists(); 
472       boolean hasFinalizedTmp = getFinalizedTmp().exists(); 
473       boolean hasCheckpointTmp = getLastCheckpointTmp().exists(); 
之后判断个各种状态产什么的标志性文件是否存在,根据不同文件存在的情况返回不同的状态。
根据不同的返回状态,同样是该类中的doRecover方法进行处理,
[java] 
534     public void doRecover(StorageState curState) throws IOException { 
535       File curDir = getCurrentDir(); 
536       String rootPath = root.getCanonicalPath(); 
537       switch(curState) { 
538       case COMPLETE_UPGRADE:  // mv previous.tmp -> previous 
539         LOG.info("Completing previous upgrade for storage directory " 
540                  + rootPath + "."); 
541         rename(getPreviousTmp(), getPreviousDir()); 
542         return; 

补充:软件开发 , Java ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,