本部分主要介绍DN中的数据的存储和管理,我们知道从逻辑上来看我们把数据存储到HDFS这个文件系统中,但是具体数据在每个DN上是如何存储的呢,这其中就牵扯到几个比较大的类DataStorage、Storage、FSDataset等等。一开始读DN源代码这部分就搞得不是很清楚,现在理一下思路,也算给刚开始看得童鞋一些提示。
在配置hdfs-site.xml的时候我们会配置这样一个选项
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数据管理中起着怎么样的作用。
public class DataStorage extends Storage {
从DataStorage类的声明可以看出DataStorage是用于DN数据管理的Storage的特殊类,那么很容易就会想到NN中也有一个这样的特殊类(是的,FSImage),torage类的主要作用就是存储两者公共的一些信息。
我们来看一下在DN启动时,DataStorage起到了什么样的作用。
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的初始化,
59 DataStorage() { 60 super(NodeType.DATA_NODE); 61 storageID = ""; 62 }主要工作还是声明自己存储的类型。下面接着看recoverTransitionRead方法,核心代码如下:
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 }