zoukankan      html  css  js  c++  java
  • HDFS的block Id与generation stamp

    hdfs的数据是以block为单位存储的,所以了解block的结构对理解hdfs的工作机制非常重要。

    先来看一下Block类,它含有三个成员:blockId,numBytes和generationStamp。numBytes即block的大小,而另外两个分别是什么呢?blockId是block的标识符,可以从block文件名中看到,例如${hadoop.tmp.dir}/dfs/data/current/blk_826540629399449945,这一串数字就是blockId。同目录下另一个meta文件,如blk_826540629399449945_1017.meta,1017即是generationStamp。从Block类本身可以看到,generationStamp在compare、equals等操作上起到一个对blockId的辅助作用,由此猜测多个blocks可能拥有相同的blockId,彼此的generationStamp不同。

    根据[1],早期block id是一个64位数随机数。当时实现比较简单,并没有判重,所以如果两个block碰巧得到同样的block id,系统会误认为是多余的备份block,而将其中一些删除。这样这个block很有可能出错,包含它的文件则损坏。解决的办法有两个,一是记录好所有使用过的block id,以实现判重功能;二是以一种不会重复的方式生成block id,比如顺序生成。顺序生成的缺点有3个,1是现有的系统迁移困难,所有的block都要重新命名;2是用完了64位数后仍然有麻烦;3是要记录好最高的block id。[1]暂时实现了判重功能。

    判重并不是最优的方法,因为它需要额外的工作,而且随着文件系统变得庞大将变重。假设用一个Hash实现判重,一个1PB的文件系统,假设1个block大小64MB,则包含有16M个block id,每个id为8个byte,则需要一个128MB的Hash表,这对于一个本身就很复杂的NameNode是个不小的压力。[2]中提出了一种综合的方法,给一个文件的所有block指定一个相同的range id(5个byte)作为它们block id的高位,然后按顺序每个block生成剩余的3个byte。较之前的单纯判重,好处在于减小了判重的数量;同时又方便管理同一个文件的block,因为它们的block id是连续的。[2]也指出这种方法的问题,当一个文件被删除时,此range id要从系统中抹去,如果此时某个包含此文件某block的数据结点掉线了,在它重新上线之后,它又带回这个已经无效的range id。所以需要timestamps,即creation time of the file,当两个文件碰巧有相同的range id时,根据timestamps来判定谁是最新的文件,旧的文件将被删除。[2]中能看到Doug Cutting和Sameer Paranjpye的一些其它討論,比如range-id也采用顺序生成(又回到随机VS顺序的问题上)。

    [1]和[2]都是在07年的0.1版本上的討論,现在0.20.2的版本是什么情况呢?我们先来看一下代码吧!FSNamesystem的allocateBlock方法:

      private Block allocateBlock(String src, INode[] inodes) throws IOException {
        Block b = new Block(FSNamesystem.randBlockId.nextLong(), 0, 0); 
        while(isValidBlock(b)) {
          b.setBlockId(FSNamesystem.randBlockId.nextLong());
        }
        b.setGenerationStamp(getGenerationStamp());
        b = dir.addBlock(src, inodes, b);
        NameNode.stateChangeLog.info("BLOCK* NameSystem.allocateBlock: "
                                     +src+ ". "+b);
        return b;
      }

    这里block id还是用一个随机产生器生成的,并且用一个Map来判重,并没有上面提到的range id的概念。同时,赋与block一个GenerationStamp,此stamp是文件系统里的全局变量,会在每次创建新文件及其它一些block操作时顺序增长。关于它的具体作用是不是[2]中所提到的,还需要进一步阅读代码。而关于block id的顺序生成的问题上,今年在[3]中又有了新的討論,可能要等到0.23.0的版本才能看到結果吧。

    参考:
    [1] potential conflict in block id's, leading to data corruption
        https://issues.apache.org/jira/browse/HADOOP-146
    [2] dfs should allocate a random blockid range to a file, then assign ids sequentially to blocks in the file
        https://issues.apache.org/jira/browse/HADOOP-158
    [3] Sequential generation of block ids
        https://issues.apache.org/jira/browse/HDFS-898

  • 相关阅读:
    118/119. Pascal's Triangle/II
    160. Intersection of Two Linked Lists
    168. Excel Sheet Column Title
    167. Two Sum II
    172. Factorial Trailing Zeroes
    169. Majority Element
    189. Rotate Array
    202. Happy Number
    204. Count Primes
    MVC之Model元数据
  • 原文地址:https://www.cnblogs.com/aaronwxb/p/2687587.html
Copyright © 2011-2022 走看看