设为首页 收藏本站
查看: 482|回复: 0

[经验分享] hadoop源码解析---INodeReference机制

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2016-7-7 09:06:13 | 显示全部楼层 |阅读模式
本文主要介绍了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对象。
图1-2给出了使用INodeReference后的文件目录树。


INodeReference代码实现
INodeReference是一个抽象类,它拓展自INode类,所以INodeReference及其子类是可以添加到文件系统目录树中以替代原有的INodeFile节点的。INodeReference定义了referred字段,这个字段用于保存当前INodeReference类指向的INode节点,所以WithName和RstReference,referred字段就指向了WithCount对象,对于WithCount,referred指向了真正的INode对象。INodeReference还定义了getReferredINode()方法,在文件系统目录树的操作中,如果判断当前节点是一个引用节点,则会调用getReferredINode()方法获取INodeReference指向的INode对象。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public abstract class INodeReference extends INode {
    private INode referred;//指向的INode节点
    public INodeReference(INode parent,INode referred){
        super(parent);
        this.referred = referred;
    }
    public final INode getReferredINode() {  //获取指向的INode节点
        return referred;
    }
    public final void setReferredINode(INode referred) {
        this.referred = referred;
    }
    //...
}



然后,我们在来看看WithCount类的实现。
WithCount类定义了一个集合字段withNameList用于保存所有指向这个WithCount对象的WithName对象集合。WithCount类还定义了addReference()方法,任何指向WithCount对象的WithName对象以及DstReference对象都需要调用这个方法来添加指向关系。对于指向这个WithCount对象的DstReference对象,addReference()方法会将这个对象设置为自己的父INode节点;而对于WithName对象,addReference()方法则将这个对象放入withNameList集合中保存。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public static class WithCount extends INodeReference {
    //保存所有指向这个WithCount对象的WithName对象的集合
    private final List<WithName> withNameList = new ArrayList<WithName>();
     
    public WithCount(INodeReference parent,INode referred) {
        super(parent,referred); //调用父类的构造方法,指向文件系统目录树中的INode
        Preconditions.checkArgument(!referred.isReference());
        refferred.setParentReferenct(this); //设置真实INode的父节点为当前WithCount对象
    }
     
    public void addReferenct(INodeReference ref){
        if ( ref instanceof WithName) { //如果是WithName对象,则加入withNameList
            WithName refWithName = (WithName) ref;
            int i = Collections.binarySearch(withNameList, refWithName,WITHNAME_COMPARATOR);
            Preconditions.checkState(i<0);
            withNameList.add(-i-1,refWithName);
        } else if (ref instanceof DstReference) { //如果是DstReference对象,则设置为父节点
            setParentReference(ref);
        }
    }
    //...
}



看完WithCount后,在看看WithName和DstReference。WithName类定义了name字段用于保存重命名前文件的名称,同事定义了lastSnapshotId字段用于保存WithName对象构造时源路径的快照版本号。DstReference类的实现就更简单了,只定义了一个dstSnapshotId字段用于保存重命名操作前目标路径的最新快照的版本号。WithName和DstReference在构造时都会调用父类的构造方法指向WithCount对象,同时还会调用WithCount.addReference()方法配置WithCount对象。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public static class WithName extend INodeReference {
    private final byte[] name;//重命名前的文件名
    private final int lastSnapshotId;
    public WithName(INodeDirectory parent,WithCount referred,bytep[] name,int lastSnapshotId){
        super(parent,referred); //调用父类构造方法,指向WithCount节点
        this.name = name;
        this.lastSnapshotId = lastSnapshotId;
        referred.addReferenct(this); //调用WithCount.addReferenct()
     }
     //...
}

public static class DstReference extends INodeReference {
    private final int dstSnapshotId;
    public DstReference (INodeDirectory parent,WithCount referred,final int dstSnapshotId){
    super(parent,referred);
    this.lastSnapshotId = lastSnapshotId;
    referred.addReferenct(this); //调用WithCount.addReferenct()
  }
  //..
}






运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-240529-1-1.html 上篇帖子: hadoop的安全模式和目录快照 下篇帖子: CentOS上编译hadoop 2.7
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表