HFile是参照谷歌的SSTable存储格式进行设计的,所有的数据记录都是通过它来完成持久化,其内部主要采用分块的方式进行存储,如图所示:
每个HFile内部包含多种不同类型的块结构,这些块结构从逻辑上来讲可归并为两类,分别用于数据存储和数据索引(简称数据块和索引块),其中数据块包括:
(1) DATA_BLOCK:存储表格数据
(2) BLOOM_CHUNK:存储布隆过滤器的位数组信息
(3) META_BLOCK:存储元数据信息
(4) FILE_INFO:存储HFile文件信息
索引块包括:
表格数据索引块(ROOT_INDEX、INTERMEDIATE_INDEX、LEAF_INDEX)
在早期的HFile版本中(version-1),表格数据是采用单层索引结构进行存储的,这样当数据量上升到一定规模时,索引数据便会消耗大量内存,导致的结果是Region加载效率低下(A region is not considered opened until all of its block index data is loaded)。
因此在version-2版本中,索引数据采用多层结构进行存储,加载HFile时只将根索引(ROOT_INDEX)数据载入内存,中间索引(INTERMEDIATE_INDEX)和叶子索引(LEAF_INDEX)在读取数据时按需加载,从而提高了Region的加载效率。
元数据索引块(META_INDEX)
新版本的元数据索引依然是单层结构,通过它来获取元数据块信息。
布隆索引信息块(BLOOM_META)
通过索引信息来遍历要检索的数据记录是通过哪一个BLOOM_CHUNK进行映射处理的。
从存储的角度来看,这些数据块会划分到不同的区域进行存储。
Trailer区域
该区域位于文件的最底部,HFile主要通过它来实现相关数据的定位功能,因此需要最先加载,其数据内容是采用protobuf进行序列化处理的,protocol声明如下: