hadoop源码解析---INodeReference机制
来源:互联网 发布:成都软件专修学院 编辑:程序博客网 时间:2024/06/06 12:23
在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对象。
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()
}
//..
}
原文转自:乐搏学院http://www.learnbo.com/front/article/cmsIndex
- hadoop源码解析---INodeReference机制
- hadoop心跳机制源码解析
- Hadoop源码解析之java动态代理机制
- hadoop心跳机制解析
- hadoop心跳机制解析
- Hadoop 心跳机制解析
- Hadoop 源码解析
- hadoop源码解析参考
- Hadoop RPC 源码解析
- hadoop源码解析
- JNI机制源码解析
- Handler机制源码解析
- Hadoop源码之RPC机制
- Hadoop心跳机制源码分析
- Hadoop心跳机制源码分析
- Hadoop心跳机制源码分析
- Hadoop心跳机制源码分析
- Hadoop RPC机制+源码分析
- 阿里云Ubuntu搭建git服务器
- Linux启动/停止/重启Mysql数据库的方法
- 从零学起vue(学习笔记2)
- MySQL主从同步(binlog方式)与主从切换
- Mac中为SourceTree设置代理登陆
- hadoop源码解析---INodeReference机制
- Android +camara
- Android系统设置命令— android.provider.Settings
- Maven打包war
- 日间模式切换
- Java实现MD5加密(一)
- 监听输入框
- 【LeetCode】Best Time to Buy and Sell Stock II 解题报告
- RHEL7--UNIT14-linux设备访问