HBase 加载Hfile时的读取过程

Hfile分为4部分,其中loadOnOpen section 和trailer这2部分是open file时就会加载到内存的。

HBase 加载Hfile时的读取过程

Step1:

读取文件末尾的4Bytes,得到Hfile format版本号,进而知道Trailer部分的大小, v2和v3都固定为4096Bytes;

Step2:

读取文件末尾的4096Bytes,这部分整体作为一个block,包含一些重要的元数据信息,目前有15个,分为以下几类;

偏移量:loadOnOpenDataOffset、fileinfoOffset、firstDataBlockOffset、lastDataBlockOffset;

数量和大小:totalUncomressedBytes、entryCount、dataIndexCount、metaIndexCount、uncompressedDataIndexSize、numDataIndexLevels

算法:compressionCodec、comparatorClassName、encryptionKey

版本号:majorVersion、minorVersion

其中,fileinfoOffset在v2以后已经没有实际用途

示例:

fileinfoOffset=1231091280,
loadOnOpenDataOffset=1231084052,
dataIndexCount=143,
metaIndexCount=0,
totalUncomressedBytes=4052639474,
entryCount=44722287,
compressionCodec=SNAPPY,
uncompressedDataIndexSize=18657365,
numDataIndexLevels=2,
firstDataBlockOffset=0,
lastDataBlockOffset=1231031083,
comparatorClassName=org.apache.hadoop.hbase.CellComparatorImpl,
encryptionKey=NONE,
majorVersion=3,
minorVersion=3

Step3:

根据loadOnOpenDataOffset读取Root Data Index block,包含numEntries和具体entry数据,每个entry包含offset、dataSize和key;

这里entry所表示的block类型与文件大小有关:

如果文件较小,Trailer中numDataIndexLevels字段的值为1,entry表示的是dataBlock,

如果文件较大,Trailer中numDataIndexLevels字段的值为2,entry表示的是leafIndexBlock

如果文件很大,Trailer中numDataIndexLevels字段的值为3,entry表示的是IntermediaLevelIndexBlock

较大和很大的阈值分别大约为100M和100G,该阈值与key长度和block大小相关;

读取分为2步:先读header(固定33字节),再根据header里面onDiskSizeWithoutHeader的值读取data部分;

这里在读取data时有个优化,会额外多读取一个header大小的数据,目的是使下一个block的读取可以一步完成,减少一次io交互,后续几个block的读取都是如此;

另外,该block末尾还存储了几个值,用于split时快速找到splitPoint:midLeafBlockOffset、midLeafBlockOnDiskSize、midKeyEntry;

Step4:

读取FileInfo该block以键值对的方式存储了一些元数据,读取之后内存中以Map形式存在,作为对比,Trailer内部只存储值,以位置顺序区分不同属性;

另外,这部分没有大小限制,可以根据需要灵活扩展,当前版本存储的属性示例如下;

BLOOM_FILTER_TYPE = ROW
DELETE_FAMILY_COUNT = 0
EARLIEST_PUT_TS = 1479619233886
KEY_VALUE_VERSION = 1
LAST_BLOOM_KEY = 69993111f5d1dfa4179d9f278192a0ad
MAJOR_COMPACTION_KEY = true
MAX_MEMSTORE_TS_KEY = 15986682
MAX_SEQ_ID_KEY = 15986682
TIMERANGE = 1479619233886....1577672100675
hfile.AVG_KEY_LEN = 73
hfile.AVG_VALUE_LEN = 5
hfile.CREATE_TIME_TS = 1577728182220
hfile.LASTKEY = 69993111f5d1dfa4179d9f278192a0ad/tag:userkn_zhengxin_list/1575836971202/Put/vlen=0/mvcc=0

Step5:

读取General BloomFilter Meta And Index

BloomFilter block的index固定只有一层,结构与RootDataIndex 类似;

meta部分额外包含了几个与bloom相关的算法和统计信息:totalByteSize、hashCount、hashType、totalKeyCount、totalMaxKeys;

Step6:

读取DeteleFamily BloomFilter Meta And Index

该block结构与General BloomFilter一致;

上一篇:HBase rpc框架介绍


下一篇:React开发(186):react 父调用子组件的方法