目录
Bloom Block 和 Bloom Index Block
本文我们从HFile的逻辑结构和HFile的物理结构两方面进行分析。
逻辑结构:
HFile文件主要分为4个部分:
- Scanned Block 这个部分包含3种数据块,DataBlock LeafIndexBlock BloomBlock 其中,DataBlock存储用户的KeyValue数据,leafIndexBlock种存储索引树的叶子节点数据。BloomBlock存储布隆过滤器相关数据。
- Non-scanned Block 主要包括MetaBlock和中间节点数据。
- Load-on-open 这部分数据会在RegionServer打开Hfile时直接加载到内存中(根据trailer记录的偏移值和长度)。
- Trailer 这部分主要记录了Hfile的版本信息和其他各个部分的偏移值,优先加载到内存,然后根据保存的Load-on-open的偏移量计算出Load-on-open的长度,在将其加载到内存。
物理结构:
HFile文件由各种类型的Block构成。block的大小默认64K.所有的Block都拥有相同的数据结构。
每个block都包含了BlockHeader和BlockData.其中BlockHeader主要存储Block相关元数据,BlockData用来存储具体数据。
BlockHeader中最核心的字段有BlockType字段,表示该Block的类型。
针对BlockType,Hbase定义了8种BlockType。
其中对于Data Block这种类型来说,Block Data保存的就是用户需要存储的数据。每一个KeyValue对应都由4部分组成
- KeyLength
- ValueLength
- Key key包含:rowKey,ColumnFamily,Column Qualifier, TimeStamp以及KeyType.其中keyType又包括: put,delete,deleteColumn,DeleteFamily.
- Value 用户写入的实际数据
Bloom Block 和 Bloom Index Block
对于给定的key,经过布隆过滤器处理就可以知道该Hfile中是否存在待检索key,不存在则不需要遍历查找该文件,降低了实际IO次数,提高随机读性能。
布隆过滤器通常会存储在内存中。所以布隆过滤器整个过程处理耗时基本可以忽略。
在Hbase中,为每个Hfile都分配了对应的位数组,keyValue在写入Hfile时会先对key经过多个hash映射,之后将对应的数组位置设为1,get请求进来时在使用相同的hash函数进行映射,如果对应数组上存在0,表示get请求到的key不再该Hfile中。可以想象,随着Hfile文件越来越大,里面存储的keyValue值越多,位数组就会相应越大,一旦位数组太大就不适合存在内存中了。因此在V2版本将位数组拆分成了多个位数组。一部分连续的key使用一个位数组,这样,一个Hfile就会有多个位数组,针对每个key数组有对应的索引,用来定位到具体的位数组。
Bloom Index Block位于Load-on-open部分,在regionserver读取hfile的时候会被直接加载到内存。
一次get请求根据布隆过滤器执行大概约3步:
- 首先根据待查找key在Bloom Index Block所有的索引项中根据BlockKey进行二分查找,定位到对应的Bloom Index Entry
- 在根据Bloom Index Entry 中BlockOffset以及BlockOndiskSize加载该key对应的位数组。
- 对key进行hash映射,根据结果判断所在位是1还是0.
hfile关于索引的Block
根据索引层级的不同,HFile种索引结构分为 single-level(单层索引)和multi-level(多层索引,一般为2-3级)。
随着Hfile文件越来越大,DataBlock越来越多,索引的数据也就越来越大,以及无法全部加载到内存,索引可以使用多级索引,只加载部分索引,从而降低内存使用空间。
关于索引的Block有3种,
- root Index Block (根节点) 位于load-on-open部分,会在regionServer打开Hfile时加载到内存中
- intermediate Index Block (中间节点) 位于Non-Scanned-block部分。
- Leaf Index Block(叶子节点)。位于Scanned Block,直接指向实际的Data Block
在root Index Block 根索引块中记录了MidKey的相关信息,这些信息用在对Hfile进行split操作时,快速定位Hfile的切分点位置。
我们也可以通过Hbase Hfile的相关命令来对hfile进行查看。