[置顶] HFile V2介绍[0.92到0.98之前的版本]

     hbase 0.92版本中,为了改进在大数据存储下的效率,HFile做了改变。HFile V1的主要问题是,你需要加载(load)所有的单片索引和BloomFilter到内存中,这会导致每台服务器有数GB的内存被块索引消耗掉,这对域服务器的可扩展性和性能有显著的负面影响。此外,由于直到加载完所有块索引数据之后,才能认为域启动完成,因此这样的块索引大小会明显地拖慢域的启动速度。 为了解决这个问题,v2引入了多级索引[一个根索引块和多个叶块,只有根索引(索引数据块)必须一直保存在内存中,叶索引以块的级别存储,这意味着它是否在内存中出现取决于块是否在内存中出现。叶索引仅在加载块时被加载到内存中,并且在块移出时被移出内存。此外,叶级别索引的结构化方式允许在不进行反序列化的情况下,对键进行二叉搜索]和分块BloomFilterHFile v2改进了速度,内存和缓存利用率。

 HFile V2的文件存储格式如下图:

 [置顶] HFile V2介绍[0.92到0.98之前的版本]_第1张图片

HFile的组成分成四部分,分别是Scanned Block(数据block)、Non-Scanned block(元数据block)、Load-on-open(在hbase运行时,HFile需要加载到内存中的索引、bloom filter和文件信息)以及trailer(文件尾)

HFile V2中根据key查找数据的过程如下:

1)先在内存中对HFile的root索引进行二分查找,如果支持多级索引,则定位到leaf index/intermediate index,如果是单级索引,则定位到数据块data block;

2)如果支持多级索引,则会从cache/hdfs中读取leaf/intermediate index chunk,在leaf/intermediate chunk根据key值进行二分查找(leaf/intermediate index chunk支持二分查找),找到对应的data block。

3)从cache/hdfs中读取数据块;

4)在数据块中遍历查找对应的数据。

DataBlock

DataBlock是用于存储具体kv数据的block,相对于索引和meta(这里的meta是指bloom filter)DataBlock的格式比较简单。

在DataBlock中,KeyValue的分布如下图,在KeyValue后面跟一个timestamp。

    [置顶] HFile V2介绍[0.92到0.98之前的版本]_第2张图片

HFileIndex

     

HFile中的index level是不固定的,根据不同的数据类型和数据大小有不同的选择.

      主要有两类,一类是single-level(单级索引),另一类是multi-level(多级索引,索引block无法在内存中存放,所以采用多级索引)。具体见

HFileBlockIndex类

[Writes the block index into the output stream. Generate the tree from bottom up. The leaf level is written to disk as a sequence of inline blocks, if it is larger than a certain number of bytes. If the leaf level is not large enough, we write all entries to the root level instead. After all leaf blocks have been written, we end up with an index referencing the resulting leaf index blocks. If that index is larger than the allowed root index size, the writer will break it up into reasonable-size intermediate-level index block chunks write those chunks out, and create another index referencing those chunks. This will be repeated until the remaining index is small enough to become the root index. However, in most practical cases we will only have leaf-level blocks and the root index, or just the root index.]

HFile中的index chunk有两大类,分别是root index chunknonRoot index chunk。  

                 nonRoot index chunk又分为interMetadiate index chunkleaf index chunk,但intermetadiate index chunk和leaf index                chunk在内存中的分布是一样的。

               对于meta block和bloom block,采用的索引是single-level形式,采用single-level时,只用root index chunk来保存指向block的索引信息(root_index-->xxx_block)。

                对于数据规模决定是否写入 leaf index和bloom block。

                 a、一开始的时候,HFile的data block数量较少时,采用的是single level(root_index-->data_block),索引的searchTreeLevel=2

                 b、当data block数量较多时,采用的是multi-level。

                 root Index越来越大,随之所耗内存增大,会以多层结构存储数据索引,使用root index chunk和leaf index chunk来保存索引信息(root_index-->leaf_index-->data_block),索引的searchTreeLevel=2

                  但当data block数量很多时,root index 再内存无法存放的时候,就变成三级索引,使用root index chunk、intermetadiate index chunk和leaf index chunk来保存指向数据的索引

             (root_index-->intermediate_index-->leaf_index-->data_block),索引的searchTreeLevel=3

                 

Fileds for midKey:
          这部分数据是Optional的,保存了一些midKey信息,可以快速地定位到midKey,常常在HFileSplit的时候非常有用。

MetaIndex:
           即meta的索引数据,和data index类似,但是meta存放的是BloomFilter的信息

FileInfo:

           保存了一些文件的信息,如lastKey,avgKeylen,avgValueLen等等,一会我们将会写程序将这部分内容解析出来并打印看看是什么东西。同样,FileInfo使用了Protobuf来进行序列化。

Bloom filter metadata:

            分为GENERAL_BLOOM_META[key是否存储在hbase]及DELETE_FAMILY_BLOOM_META[确定key是否已经被删除]二种

   

      

Bloom meta index在磁盘中的格式如上图所示。

Version:表示版本;

totalByteSize:表示bloom filter的位组的bit数。

HashCount:表示一个key在位组中用几个bit位来进行定位。

HashType:表示hash函数的类型。

totalKeyCount:表示bloom filter当前已经包含的key的数目.

totalKeyMaxs:表示bloom filter当前最多包含的key的数目.

numChunks:表示bloom filter中包含的bloom filter block的数目.

comparatorName:表示比较器的名字.

HFile 详解图: 

 


你可能感兴趣的:([置顶] HFile V2介绍[0.92到0.98之前的版本])