hadoop源码解析---INodeReference机制

本文主要介绍了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对象。

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集合中保存。

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对象。

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()
  }
  //..
}
时间: 2024-08-08 15:49:30

hadoop源码解析---INodeReference机制的相关文章

源码解析——消息机制

映象笔记的链接:源码解析--消息机制

Hadoop源码解析之: TextInputFormat如何处理跨split的行

转自:http://blog.csdn.net/bluishglc/article/details/9380087 我们知道hadoop将数据给到map进行处理前会使用InputFormat对数据进行两方面的预处理: 对输入数据进行切分,生成一组split,一个split会分发给一个mapper进行处理. 针对每个split,再创建一个RecordReader读取Split内的数据,并按照<key,value>的形式组织成一条record传给map函数进行处理. 最常见的FormatInput

Storm的BaseBasicBolt源码解析ack机制

我们在学习ack机制的时候,我们知道Storm的Bolt有BaseBasicBolt和BaseRichBolt.在BaseBasicBolt中,BasicOutputCollector在emit数据的时候,会自动和输入的tuple相关联,而在execute方法结束的时候那个输入tuple会被自动ack.在使用BaseRichBolt需要在emit数据的时候,显示指定该数据的源tuple要加上第二个参数anchor tuple,以保持tracker链路,即collector.emit(oldTup

Hadoop源码解析之 rpc通信 client到server通信

rpc是Hadoop分布式底层通信的基础,无论是client和namenode,namenode和datanode,以及yarn新框架之间的通信模式等等都是采用的rpc方式. 下面我们来概要分析一下Hadoop2的rpc. Hadoop通信模式主要是C/S方式,及客户端和服务端的模式. 客户端采用传统的socket通信方式向服务端发送信息,并等待服务端的返回. 服务端采用reactor的模式(Java nio)的方式来处理客户端的请求并给予响应. 一.客户端到服务端的通信 下面我们先分析客户端到

hadoop源码解析2 - conf包中Configuration.java解析

1 Hadoop Configuration简介    Hadoop没有使用java.util.Properties管理配置文件,也没有使用Apache Jakarta Commons Configuration管理配置文件,而是使用了一套独有的配置文件管理系统,并提供自己的API,即使用org.apache.hadoop.conf.Configuration处理配置信息. org.apache.hadoop.conf目录结构如下: 2 Hadoop配置文件的格式解析    Hadoop配置文件

Hadoop源码解析 1 --- Hadoop工程包架构解析

1 Hadoop中各工程包依赖简述     Google的核心竞争技术是它的计算平台.Google的大牛们用了下面5篇文章,介绍了它们的计算设施.     GoogleCluster: http://research.google.com/archive/googlecluster.html     Chubby:http://labs.google.com/papers/chubby.html     GFS:http://labs.google.com/papers/gfs.html   

安卓中的事件分发机制源码解析

安卓中的事件分发机制主要涉及到两类控件,一类是容器类控件ViewGroup,如常用的布局控件,另一类是显示类控件,即该控件中不能用来容纳其它控件,它只能用来显示一些资源内容,如Button,ImageView等控件.暂且称前一类控件为ViewGroup类控件(尽管ViewGroup本身也是一个View),后者为View类控件. 安卓中的事件分发机制主要涉及到dispatchTouchEvent(MotionEvent ev).onInterceptTouchEvent(MotionEvent e

jquery源码解析:jQuery数据缓存机制详解1

jQuery中有三种添加数据的方法,$().attr(),$().prop(),$().data().但是前面两种是用来在元素上添加属性值的,只适合少量的数据,比如:title,class,name等.对于json这种数据量大的,就适合用data方法来添加,而data方法就是jQuery缓存机制最重要的方法. jQuery中为什么要用缓存机制系统呢?因为DOM元素与js对象之间互相引用,在大部分浏览器下会引起内存泄漏.为了解决这个问题,jQuery就写了一个缓存机制系统.举个例子: var di

Android View体系(五)从源码解析View的事件分发机制

相关文章 Android View体系(一)视图坐标系 Android View体系(二)实现View滑动的六种方法 Android View体系(三)属性动画 Android View体系(四)从源码解析Scroller 前言 三年前写过事件分发机制的文章但是写的不是很好,所以重新再写一篇,关于事件分发机制的文章已经有很多,但是希望我这篇是最简洁.最易懂的一篇. 1.处理点击事件的方法 View的层级 我们知道View的结构是树形的结构,View可以放在ViewGroup中,这个ViewGro