本部分主要介绍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 }
首选看到这个循环是对hdfs-site.xml这个配置文件中,配置的每个存储路径进行检查。具体检查的通过StorageDirectory的analyzeStorage方法进行,该方法会返回当前存储处于何种状态(这个状态在前边的博客中已经讲述,主要是升级过程可能造成DN处于多种状态)。如果是NORMAL说明一切正常,不作处理;如果是NON_EXISTENT说明配置项中的这个目录不存在;如果是NOT_FORMATTED,说明命令是进行格式化的操作(hadoop dfs -format),通过 format(sd, nsInfo); 方法格式化;其他状态通过sd.doRecover(curState)方法,进行处理。
通过上面的描述很容易发现StorageDirectory的对象,在处理的各个部分都起着关键作用。那么来分析下这个StorageDirectory类的主要作用,StorageDirectory是DataStorage父类Stora