频道栏目
首页 > 资讯 > 其他 > 正文

hadoop源码解析---INodeReference机制

16-07-20        来源:[db:作者]  
收藏   我要投稿

本文主要介绍了hadoop源码中hdfs的INodeReference机制。

 

在hdfs2.6版本中,引入了许多新的功能,一些原有的源代码设计也有一定的改造。一个重要的更新就是引入了快照功能。但是当HDFS文件或者目录处于某个快照中,并且这个文件或者目录被重命名或者移动到其他路径时,该文件或者目录就会存在多条访问路径。INodeReference就是为了解决这个问题产生的。

 

问题描述

/a是hdfs中的一个普通目录,s0为/a的一个快照,在/a目录下有一个文件test。根据快照的定义,我们可以通过/a/test以及/a/snapshot/s0/test访问test文件。

但是当用户将/a/test文件重命名成/x/test1时,通过快照路径/a/snapshot/s0/test将无法访问test文件,这种情况是不符合快照规范的。

 

引入INodeReference

为了解决上述问题,hdfs引入了INodeReference类。图1-1给出了INodeReference的继承关系图。这里的WithName,WithCoount,DstReference都是INodeReference的子类,同时也是INodeReference的内部类。WithName对象用于替代重命名操作前源路径中的INode对象,DstReference对象则用于替代重命名操作后目标路径中的INode对象,WithName和DstReference共同指向了一个WithCount对象,WithCount对象则指向了文件系统目录树中真正的INode对象。

wKiom1d-a8jzh56GAAAjULQfl1E627.png

图1

INodeReference代码实现

INodeReference是一个抽象类,它拓展自INode类,所以INodeReference及其子类是可以添加到文件系统目录树中以替代原有的INodeFile节点的。INodeReference定义了referred字段,这个字段用于保存当前INodeReference类指向的INode节点,所以WithName和RstReference,referred字段就指向了WithCount对象,对于WithCount,referred指向了真正的INode对象。INodeReference还定义了getReferredINode()方法,在文件系统目录树的操作中,如果判断当前节点是一个引用节点,则会调用getReferredINode()方法获取INodeReference指向的INode对象。

publicabstractclassINodeReferenceextendsINode{
privateINodereferred;//指向的INode节点
publicINodeReference(INodeparent,INodereferred){
super(parent);
this.referred=referred;
}
publicfinalINodegetReferredINode(){//获取指向的INode节点
returnreferred;
}
publicfinalvoidsetReferredINode(INodereferred){
this.referred=referred;
}
//...
}

然后,我们在来看看WithCount类的实现。

WithCount类定义了一个集合字段withNameList用于保存所有指向这个WithCount对象的WithName对象集合。WithCount类还定义了addReference()方法,任何指向WithCount对象的WithName对象以及DstReference对象都需要调用这个方法来添加指向关系。对于指向这个WithCount对象的DstReference对象,addReference()方法会将这个对象设置为自己的父INode节点;而对于WithName对象,addReference()方法则将这个对象放入withNameList集合中保存。

publicstaticclassWithCountextendsINodeReference{
//保存所有指向这个WithCount对象的WithName对象的集合
privatefinalListwithNameList=newArrayList();

publicWithCount(INodeReferenceparent,INodereferred){
super(parent,referred);//调用父类的构造方法,指向文件系统目录树中的INode
Preconditions.checkArgument(!referred.isReference());
refferred.setParentReferenct(this);//设置真实INode的父节点为当前WithCount对象
}

publicvoidaddReferenct(INodeReferenceref){
if(refinstanceofWithName){//如果是WithName对象,则加入withNameList
WithNamerefWithName=(WithName)ref;
inti=Collections.binarySearch(withNameList,refWithName,WITHNAME_COMPARATOR);
Preconditions.checkState(i<0);
withNameList.add(-i-1,refWithName);
}elseif(refinstanceofDstReference){//如果是DstReference对象,则设置为父节点
setParentReference(ref);
}
}
//...
}

看完WithCount后,在看看WithName和DstReference。WithName类定义了name字段用于保存重命名前文件的名称,同事定义了lastSnapshotId字段用于保存WithName对象构造时源路径的快照版本号。DstReference类的实现就更简单了,只定义了一个dstSnapshotId字段用于保存重命名操作前目标路径的最新快照的版本号。WithName和DstReference在构造时都会调用父类的构造方法指向WithCount对象,同时还会调用WithCount.addReference()方法配置WithCount对象。

publicstaticclassWithNameextendINodeReference{
privatefinalbyte[]name;//重命名前的文件名
privatefinalintlastSnapshotId;
publicWithName(INodeDirectoryparent,WithCountreferred,bytep[]name,intlastSnapshotId){
super(parent,referred);//调用父类构造方法,指向WithCount节点
this.name=name;
this.lastSnapshotId=lastSnapshotId;
referred.addReferenct(this);//调用WithCount.addReferenct()
}
//...
}

publicstaticclassDstReferenceextendsINodeReference{
privatefinalintdstSnapshotId;
publicDstReference(INodeDirectoryparent,WithCountreferred,finalintdstSnapshotId){
super(parent,referred);
this.lastSnapshotId=lastSnapshotId;
referred.addReferenct(this);//调用WithCount.addReferenct()
}
//..
}

 

 

相关TAG标签
上一篇:RedHat 7.2 KVM通过V2V迁移VMware的虚拟机
下一篇:SEOer需要从哪些角度去写好软文
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站