最新版的HFile主要做了两个改进,这两个改进都主要是为了降低内存使用和启动时间,思路都是将它们切分为多个block,填满就写出去,这也降低了writer的内存占用:
1. 增加了树状结构的数据块索引(data block index)支持。原因是在数据块的索引很大时,很难全部load到内存,比如当前的一个data block会在data block indxe区域对应一个数据项,假设每个block 64KB,每个索引项64Byte,这样如果每条机器上存放了6TB数据,那么索引数据就得有6GB,因此这个占用的内存还是很高的。通过对这些索引以树状结构进行组织,只让顶层索引常驻内存,其他索引按需读取并通过LRU cache进行缓存,这样就不需要将全部索引加载到内存。
相当于把原先平坦的索引结构以树状的结构进行分散化的组织。现在的index block也是与data block一样是散布到整个文件之中,而不再是单纯的在结尾处。同时为支持对序列化数据进行二分查找,还为非root的block index设计了新的"non-root index block"。
具体实现来看,比如在写入HFile时,在内存中会存放当前的inline block index,当inline block index大小达到一定阈值(比如128KB)时就直接flush到磁盘,而不再是最后做一次flush,这样就不需要在内存中一直保持所有的索引数据。当所有的inline block index生成之后,HFile writer会生成更上一级的block index,它里面的内容就是这些inline block index的offset,依次递归,逐步生成更上层的block index,上层的包含的就是下层的offset,直到最顶层大小小于阈值时为止。所以整个过程就是自底向上的通过下层index block逐步构建出上层index block。
2. 之前的bloom filter数据是存放在单独的一个meta block里,新版里它将可以被存为多个block。优点类似于第一个改动,这就允许在处理一个查询时不必将所有的数据都load到内存。
具体格式如下:
旧格式如下:
上图中Trailer部分具体格式如下:
参考资料:
https://issues.apache.org/jira/browse/HBASE-3857
Build a tree structure data block index inside of the HFile
Add Bloom Block Index Support
HFile:A Block-Indexed File Format to Store Sorted Key-Value Pairs