由于本人愚笨,光阴似箭、日月如梭、随着年龄的增长,看着那么多大牛,写出了那么多知名的框架,对于框架的知识,不仅仅想知道怎么去使用它,还想为什么别人是这样
设计,这样声明类和接口,就好比刚刚开始看的HDFS文件系统一样,为什么会有Fimage类对象和edits对象。
我脑子里面总是在想,很多事情是从简单到复杂的,看hadoop的代码也是,所以我就从hadoop的最简单、最基础的地方开始。我首先下载了hadoop的源码较老的版本。
hadoop 0.20.0版本,这个版本还是ant ivy编译的文件。因为之前的确遇到很多问题,包括调试23版本的代码,感觉有点无可是从的感觉;总之,痛定思痛,我开始debug了。呵呵
现在开心记录自己的debug的种种,加油
1.
首先我从start-dfs.sh这个文件开始调试。
下面这一段是我在bin\hadoop文件中修改的,添加了调试配置。
# figure out which class to run
if [ "$COMMAND" = "namenode" ] ; then
CLASS='org.apache.hadoop.hdfs.server.namenode.NameNode'
HADOOP_OPTS="$HADOOP_OPTS $HADOOP_NAMENODE_OPTS"
HADOOP_OPTS="$HADOOP_OPTS -Xdebug -Xrunjdwp:transport=dt_socket,address=7777,server=y,suspend=y"
elif [ "$COMMAND" = "secondarynamenode" ] ; then
CLASS='org.apache.hadoop.hdfs.server.namenode.SecondaryNameNode'
HADOOP_OPTS="$HADOOP_OPTS $HADOOP_SECONDARYNAMENODE_OPTS"
HADOOP_OPTS="$HADOOP_OPTS -Xdebug -Xrunjdwp:transport=dt_socket,address=7778,server=y,suspend=y"
elif [ "$COMMAND" = "datanode" ] ; then
CLASS='org.apache.hadoop.hdfs.server.datanode.DataNode'
HADOOP_OPTS="$HADOOP_OPTS $HADOOP_DATANODE_OPTS"
HADOOP_OPTS="$HADOOP_OPTS -Xdebug -Xrunjdwp:transport=dt_socket,address=7779,server=y,suspend=y"
2.开始调试。
本地windows客户端,监听远程端口。
先填上类图
类Namenode是就是namenode 节点类吧。
类FSnamesystem 表示的是真个HDFS的namespace;这样理解
类FSdirectory 代表是整个HDFS中所有的目录结构及其属性。
类FSimage 的实例化对象对应元数据的磁盘文件。
类FSedits 的实例化对象对应元数据的磁盘文件。edits
调试先是进入namenode 的main 方法中,然后调用namenode 中的createNameNodes方法,然后在这个方法中获得用户的输入,如果是format,进入namenode 的format方法。
在format方法中,先是判断conf文件的有效,然后获得等待格式化的edits文件目录,集合editDirsToFormat,然后遍目录;
实例化FSNamesystem对象;
代码如下:
FSNamesystem nsys = new FSNamesystem(new FSImage(dirsToFormat,
editDirsToFormat), conf);
实例化FSNamesystem对象的同时用到了FSImage对象实例,Fsimage 类中,对fsimage、fsdirectory目录进行了初始化,调用了本类中的setStorageDirectories方法,
void setStorageDirectories(Collection<File> fsNameDirs,
Collection<File> fsEditsDirs
) throws IOException {
this.storageDirs = new ArrayList<StorageDirectory>();
this.removedStorageDirs = new ArrayList<StorageDirectory>();
// Add all name dirs with appropriate NameNodeDirType
for (File dirName : fsNameDirs) {
boolean isAlsoEdits = false;
for (File editsDirName : fsEditsDirs) {
if (editsDirName.compareTo(dirName) == 0) {
isAlsoEdits = true;
fsEditsDirs.remove(editsDirName);
break;
}
}
NameNodeDirType dirType = (isAlsoEdits) ?
NameNodeDirType.IMAGE_AND_EDITS :
NameNodeDirType.IMAGE;
this.addStorageDir(new StorageDirectory(dirName, dirType));
}
// Add edits dirs if they are different from name dirs
for (File dirName : fsEditsDirs) {
this.addStorageDir(new StorageDirectory(dirName,
NameNodeDirType.EDITS));
}
}然后再回到namenode的createnamenode方法,注意下面的这段代码
nsys.dir.fsImage.format();进入FSimage类的format方法, 方法如下:
public void format() throws IOException {
this.layoutVersion = FSConstants.LAYOUT_VERSION;
this.namespaceID = newNamespaceID();
this.cTime = 0L;
this.checkpointTime = FSNamesystem.now();
for (Iterator<StorageDirectory> it =
dirIterator(); it.hasNext();) {
StorageDirectory sd = it.next();
format(sd);
}
}我百度一下,解释如下:
layoutVersion:表示是当前软件所处的版本,以此版本来决定是否允许升级,layoutVersion的默认值为-18.;(debug一下果然是-18)
namespaceId:是namespace的一个重要属性,是HDFS的身份标识,他在namenode格式化的时候产生,在namenode的整个生命周期内都不改变,当data node 注册到namnode后,会获得该namnode的namespaceId,并作为后续与namenode通信的身份标识,对于未知身份的datanode,namenode会拒绝其通信请求,namespaceId值
的产生有一个专门函数newNamespaceId,它以FSnamesyste的时间为种子产生随机数,取随机位低31位作为namespaceId。
cTime:表示Fimage 文件的创建时间。
checkpointTime:表示namespace的第一次checkpoint 时间,取当前时间值作为第一次checkpoint时间。
调试完format方法后,查看linux服务器上面的目录结构。如下:
hadoop@feixiang:/opt/hadoop20/datalog2/current$ ll
总用量 24
drwxrwxr-x 2 hadoop hadoop 4096 9月 6 16:43 ./
drwxrwxr-x 4 hadoop hadoop 4096 9月 6 16:41 ../
-rw-rw-r-- 1 hadoop hadoop 4 9月 6 16:41 edits
-rw-rw-r-- 1 hadoop hadoop 96 9月 6 16:27 fsimage
-rw-rw-r-- 1 hadoop hadoop 8 9月 6 16:41 fstime
-rw-rw-r-- 1 hadoop hadoop 101 9月 6 16:41 VERSION

被折叠的 条评论
为什么被折叠?



