DataNode之文件系统数据集FsVolumeList

BlockPoolSlice: 管理一个Block Pool在指定存储目录下的所有block.由于Data Node可以定义多个存储目录,所以Block Pool的block可能会分布在多个存储目录下,一个Block Pool会拥有多个BlockPool

Slice对象,这个BlockPool对应的所有BlockPoolSlice对象共同管理Block Pool中所有的Block

 

FSVolumeImpl: 管理Data Node一个存储目录下所有的数据块。由于一个存储目录可以存储多个Block Pool的数据块,所以FsVolumeImpl会持有这个存储目录中保存的所有BlockPoolSlice对象

 

FsVolumelList: Data Node可以定义多个存储目录,每一个存储目录下的数据块是使用FsVolumeImpl来管理的,所以Data Node定义了一个FsVolumelList保存Data Node上所有的FsVolumeImpl对象,FsVolumelList对FsDatasetImpl提供类似磁盘的服务

 

 

一 Data Node数据块副本的状态

FsDatasetImpl会有一个ReplicaMap对象,维护着Data Node上所有所有数据块副本的状态。

FINALIZED: Data Node上已经完成写操作的副本

RBW: Data Node上由客户端创建的正在进行写的副本,还没有完成写操作

RUR(Replica Under Recovery): 正在进行block恢复时的副本

RWR(Replica Waiting To Be Recovered): 如果Data Node宕机或者重启  ,所有RBW状态的的副本在Data Node重启之后,都将被加载为

RWR状态,RWR会等待块恢复操作

TEMPORARY: Data Node之间复制数据块,或者进行集群数据块平衡操作时,正在写入的副本状态就是临时状态,这个和RBW相比较,对于客户端是不可见的

 

二 BlockPoolSlice分析

Block Pool在每一个存储目录下都会有一个Block Pool目录存储数据块,那么BlockPoolSlice就是管理这个目录下所有的数据块。


如图示:就是管理着这个BP-54063261-192.168.3.101-1484123867096

目录下所有的数据块

一个块池目录可能存在current/finalized/rbw/tmp/layzPersist等文件目录。

Current目录包含了finalized、rbw以及lazyPersist等目录。

Finalized:保存了所有的FINALIZED状态的副本

Rbw:保存了RBW,RUR,RWR等状态的副本,tmp目录保存了TEMPORARY状态的副本。

以blk开始,不以meta结尾的就是数据块文件

以blk开始,以meta结尾则是数据块文件的校验文件

主要的字段

//blockpool id

privatefinal String bpid;

//这个Block Pool属于哪一个命名空间卷

privatefinal FsVolumeImpl volume;

//blockpool目录下的current目录

privatefinal File currentDir;

//finalized存储的目录

privatefinal File finalizedDir;

//lazypersist存储目录

privatefinal File lazypersistDir;

//RBW存储目录

privatefinal File rbwDir;

//存储TEMPORARY状态副本的目录

privatefinal File tmpDir;

 

BlockPoolSlice在构造的时候,会初始化finalized,tmp,rbw等字段

另外BlockPoolSlice提供了一些操作数据块副本的方法

在Block Pool目录中创建数据块副本包括以下几种情况:

>>创建TEMPORARY,RBW以及FINALIZED状态的副本。

File createTmpFile(Blockb) throws IOException {

    Filef = newFile(tmpDir,b.getBlockName());

    return DatanodeUtil.createTmpFile(b,f);

}

File createRbwFile(Blockb) throws IOException {

    Filef = newFile(rbwDir,b.getBlockName());

    return DatanodeUtil.createTmpFile(b,f);

}

>>获取Block Pool 目录下副本状态

  /**

   *获取当前block pool目录下所有数据块副本的状态,并且使用ReplicaMap来保存

   *这些副本块的状态

   *@param volumeMap

   *@param lazyWriteReplicaMap

   *@throws IOException

   */

voidgetVolumeMap(ReplicaMap volumeMap, final RamDiskReplicaTracker lazyWriteReplicaMap)

      throws IOException {

    //恢复lazypersist状态的副本

    if (lazypersistDir.exists()) {

      int numRecovered =moveLazyPersistReplicasToFinalized(lazypersistDir);

    }

 

    //将所有FINALIZED状态的副本加入ReplicaMap

    addToReplicasMap(volumeMap, finalizedDir, lazyWriteReplicaMap, true);

    //将所有RBW状态的副本加入ReplicaMap中

    addToReplicasMap(volumeMap, rbwDir, lazyWriteReplicaMap, false);

  }

三 FsVolumempl分析

DataNode 可以配置多个存储目录存储数据块文件,每一个存储目录下的数据块文件都由FsVolumeImpl管理,而每一个存储目录又可以可以保存多个Block Pool的数据块,其中每一个BlockPool 数据块的管理都是由BlockPoolSlice来管理

我们可以这样理解:

FsVolumeImpl管理的是一个存储目录下所有的数据块文件,不区分这些块属于哪一个BlockPool

BlockPoolSlice只是针对某一个BlockPool下的数据块文件进行管理

 

FsVolumeSpi接口:

/*获取当前存储目录的StorageUuID*/

public StringgetStorageID();

/*获取当前存储目录下BlockPool列表*/

public String[]getBlockPoolList();

/*获取当前存储目录下可以使用的存储空间*/

publiclong getAvailable()throws IOException;

/*获取当前存储目录的基准路径*/

public StringgetBasePath();

/*获取当前存储目录的路径*/

public StringgetPath(String bpid)throws IOException;

/*获取指定块池在当前存储目录下的finalized目录*/

public FilegetFinalizedDir(String bpid) throws IOException;

/*获取当前存储目录的存储类型:内存,磁盘,固态硬盘还是archive*/

public StorageTypegetStorageType();

/*对RBW状态的数据块预留磁盘空间,这样写数据时就不会出现磁盘空间不足*/

publicvoid reserveSpaceForRbw(longbytesToReserve);

/*释放预留的空间*/

publicvoid releaseReservedSpace(longbytesToRelease);

/*判断当前卷是否有与之对应的持久化磁盘*/

publicboolean isTransientStorage();

 

FsVolumeImpl比较重要的字段和方法

privatefinal FsDatasetImpl dataset;

//当前存储目录对应的StorageDirectory ID

privatefinal String storageID;

//存储类型

privatefinal StorageType storageType;

//<block pool id,BlockPoolSlice>映射

privatefinal Map<String, BlockPoolSlice>bpSlices

=newConcurrentHashMap<String, BlockPoolSlice>();

//当前存储目录下的current文件

privatefinal File currentDir;

//当前磁盘使用状况工具类

privatefinal DF usage;

//当前存储目录预留的磁盘空间大小

privatefinal longreserved;

private CloseableReferenceCountreference = newCloseableReferenceCount();

//rbw预留的磁盘空间

privateAtomicLongreservedForRbw;

FsVolumeImpl方法主要分为四个部分:

>>获取存储目录的存储情况

getDfsUsed/getBlockPoolUsed/getCapacity/getAvailable/getReservered/等。底层都是调用BlockPoolSlice对应方法

比如:

publiclong getDfsUsed()throws IOException {

    long dfsUsed =0;

    synchronized(dataset) {

      for(BlockPoolSlice s :bpSlices.values()) {

       dfsUsed += s.getDfsUsed();

      }

    }

    return dfsUsed;

}

>>获取存储目录的子目录

包括getCurrentDir、getRbwDir等

>>数据块操作

包括添加数据块副本,获取数据块副本数等操作

这些方法底层都是调用BloclkPoolSlice的对应方法

File addFinalizedBlock(String bpid, Block b,File f, longbytesReservedForRbw) throwsIOException {

    releaseReservedSpace(bytesReservedForRbw);

    return getBlockPoolSlice(bpid).addBlock(b,f);

  }

>>BlockPool操作

比如在当前存储目录下添加或者删除一个BlockPool的存储

  void addBlockPool(String bpid, Configurationconf) throws IOException {

    Filebpdir = newFile(currentDir,bpid);

    BlockPoolSlicebp = newBlockPoolSlice(bpid,this, bpdir, conf);

    bpSlices.put(bpid,bp);

  }

四 FsVolumeList分析

HDFS提供了一个接口类FsVolumeList,使用一个集合持有所有的FsVolumeImpl对象,然后进行所有存储目录数据块的管理

比较重要的字段

  /*

   *选择一个存储目录对应的FsVolumeImpl对象来存放数据块副本

   *目前有2种策略:

   * AvailableSpaceVolumeChoosingPolicy

   *选择有更多可用空间的的存储目录来存放副本

   * RoundRobinVolumeChoosingPolicy

   *轮询直到选择出第一个有足够空间存储目录来存放副本

   */

privatefinal VolumeChoosingPolicy<FsVolumeImpl>blockChooser;

privatefinal AtomicReference<FsVolumeImpl[]>volumes =

      newAtomicReference<>(new FsVolumeImpl[0]);

它主要提供一下三种操作:

>>获取DataNode节点状态操作:FsVolumeList提供了获取DataNode总容量,剩余总量,dfs使用量和数据块信息等方法

>>BlockPool相关操作:提供了添加和删除BlockPool的操作

 


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

莫言静好、

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值