hadoop源码解析---INodeReference机制
2016-10-17 00:00
246 查看
在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
INodeReference代码实现
INodeReference是一个抽象类,它拓展自INode类,所以INodeReference及其子类是可以添加到文件系统目录树中以替代原有的INodeFile节点的。INodeReference定义了referred字段,这个字段用于保存当前INodeReference类指向的INode节点,所以WithName和RstReference,referred字段就指向了WithCount对象,对于WithCount,referred指向了真正的INode对象。INodeReference还定义了getReferredINode()方法,在文件系统目录树的操作中,如果判断当前节点是一个引用节点,则会调用getReferredINode()方法获取INodeReference指向的INode对象。
然后,我们在来看看WithCount类的实现。
WithCount类定义了一个集合字段withNameList用于保存所有指向这个WithCount对象的WithName对象集合。WithCount类还定义了addReference()方法,任何指向WithCount对象的WithName对象以及DstReference对象都需要调用这个方法来添加指向关系。对于指向这个WithCount对象的DstReference对象,addReference()方法会将这个对象设置为自己的父INode节点;而对于WithName对象,addReference()方法则将这个对象放入withNameList集合中保存。
看完WithCount后,在看看WithName和DstReference。WithName类定义了name字段用于保存重命名前文件的名称,同事定义了lastSnapshotId字段用于保存WithName对象构造时源路径的快照版本号。DstReference类的实现就更简单了,只定义了一个dstSnapshotId字段用于保存重命名操作前目标路径的最新快照的版本号。WithName和DstReference在构造时都会调用父类的构造方法指向WithCount对象,同时还会调用WithCount.addReference()方法配置WithCount对象。
结束语:
免费学习更多精品课程,登录乐搏学院官网http://h.learnbo.cn/
原创:本文出自 “Xlows” 博客,请务必保留此出处http://xlows.blog.51cto.com/5380484/1811689
问题描述
/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
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; } //. 7fe0 .. } |
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(INodeReferenceparent,INode referred) { super (parent,referred); //调用父类的构造方法,指向文件系统目录树中的INode Preconditions.checkArgument(!referred.isReference()); refferred.setParentReferenct( this ); //设置真实INode的父节点为当前WithCount对象 } public void addReferenct(INodeReferenceref){ 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); } } //... } |
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,WithCountreferred,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,WithCountreferred, final int dstSnapshotId){ super (parent,referred); this .lastSnapshotId = lastSnapshotId; referred.addReferenct( this ); //调用WithCount.addReferenct() } //.. } |
免费学习更多精品课程,登录乐搏学院官网http://h.learnbo.cn/
原创:本文出自 “Xlows” 博客,请务必保留此出处http://xlows.blog.51cto.com/5380484/1811689
相关文章推荐
- hadoop源码解析---INodeReference机制
- hadoop源码解析---INodeReference机制 推荐
- Hadoop1.2.1源码解析系列:JT与TT之间的心跳通信机制——TT篇
- Hadoop1.2.1源码解析系列:JT与TT之间的心跳通信机制——JT篇
- Hadoop源码解析之java动态代理机制
- Hadoop1.2.1源码解析系列:JT与TT之间的心跳通信机制——JT篇
- Hadoop1.2.1源码解析系列:JT与TT之间的心跳通信机制——命令篇
- Hadoop1.2.1源码解析系列:JT与TT之间的心跳通信机制——TT篇
- Hadoop1.2.1源码解析系列:JT与TT之间的心跳通信机制——TT篇
- hadoop源码之Configuration解析
- HDFS1.0源代码解析—Hadoop的RPC机制之Server端解析
- Android的消息处理机制:Message、Handlerhe和Looper的图解及其源码解析
- Hadoop源码分析HDFS Client向HDFS写入数据的过程解析
- Android的消息处理机制:Message、Handlerhe和Looper源码解析
- 分布式系统Hadoop源码阅读与分析(一):作业调度器实现机制
- Hadoop源码分析之一(RPC机制之Server)
- Hadoop源码分析之心跳机制
- phoengap源码解析——插件机制,java和js代码互调用详解
- JVM类加载机制(ClassLoader)源码解析(3)
- JVM类加载机制(ClassLoader)源码解析