HFile文件分为以下六大部分
序号 | 名称 | 描述 |
1 | 数据块 | 由多个block(块)组成,每个块的格式为: [块头] + [key 长] + [value 长] + [key] + [value] 。 |
2 | 元数据块 | 元数据是key-value类型的值,但元数据快只保存元数据的value值,元数据的key值保存在第五项(元数据索引块)中。 该块由多个元数据值组成。 |
3 | fileInfo块 | 该块保存与HFile相关的一些信息。 fileInfo是以key值排序key-value类型的值。基本格式为: keyValue元素的个数 + (key + value类型id + value) + (key + value类型id + value) + …… |
4 | 数据索引块 | 该块的组成为: 索引块头 + (数据块在文件中的偏移 + 数据块长 + 数据块的第一个key) + (数据块在文件中的偏移 + 数据块长 + 数据块的第一个key) + …… |
5 | 元数据索引块 | 该块组成格式同数据块索引,只是某部分的意义不一样,组成格式: 索引块头 + (元数据在文件中的偏移 + 元数据value长 + 元数据key) + (元数据在文件中的偏移 + 元数据value长 + 元数据key) + …… |
6 | HFile文件尾 | 该块记录了其他各块在hfile文件中的偏移信息和其他一些元信息。组成格式如下: 文件尾 + Fileinfo偏移 + 数据块索引偏移 + 数据块索引个数 + 元数据索引偏移 + 元数据索引个数 + 数据块中未压缩数据字节数 + 数据块中全部数据的key-value个数 + 压缩代码标识 + 版本标识 |
数据块组成图如下:
Data Block Magic {‘D’, ‘A’, ‘T’, ‘A’, ‘B’, ‘L’, ‘K’, 42 } | |||
key长 | value长 | key | value |
key长 | value长 | key | value |
…… | |||
key长 | value长 | key | value |
Data Block Magic {‘D’, ‘A’, ‘T’, ‘A’, ‘B’, ‘L’, ‘K’, 42 } | |||
key长 | value长 | key | value |
key长 | value长 | key | value |
…… | |||
key长 | value长 | key | value |
Blocks …… |
数据块部分由多个block块组成,每个数据块由块头 + 多个cell(key-value对)集合组成,如上图。每个数据块的大小在创建表的列族的时候可以指定,默认为(64 * 1024)。
1. 块大小的设定由HColumnDescriptor.setBlockSize(int)指定,默认(64 * 1024)。
2. 块大小设置,块设置的越小,访问速度越快,但数据块索引越大,消耗的内存越多。因为在加载HFile时会把数据块索引全部加载到内存中。
数据块组成说明:
1. Data Block Magic – 数据块头,8字节,固定字节如下:{‘D’, ‘A’, ‘T’, ‘A’, ‘B’, ‘L’, ‘K’, 42 }。
2. key长 – 4字节整型,记录每个cell的key的长度。
3. value长 – 4字节整型,记录每个cell的value的长度。
4. key – cell的key值,byte[]类型,组成如下:
rowKey的长(2字节)+ rowKey + family的长(1字节) + family + qualify + timestampe(8字节) + keyType类型(1字节)
1)rowKey的长度不能大于0x7fff(32767).
2)rowKey不能为空。
3)family(列族)的长度不能大于0x7f(127)
4)qualify(限定符)的长度不能大于(0x7fffffff(2147483647) – row长度 – family长度)。
5. value – cell的value值,byte[]类型,value值不能为空。
例如: 在hbase中有一个表(student),其中有一个列族(info),该列族不压缩。其中的rowkey用学号表示,现在插入一个记录(rowkey=’033′, qualify=’age’, value=’19′)。那么该记录将被表示成一个cell(key-value对)保存到HFile中,那么该cell在HFile中的内容如下:
项 | 字节表示 |
key长 | {0,0,0,24} |
value长 | {0,0,0,2} |
key | {0,3}+{’0′, ’3′, ’3′}+{4}+{‘i’, ‘n’, ‘f’, ‘o’}+{‘a’, ‘g’, ‘e’}+{0,0,0,0,0,0,0,8}+{4} |
value | {’1′, ’9′} |
问题:
1. 块大小的设置策略?
2. keyType的说明?
3. compress压缩的说明?
每个元数据是key-value类型的值,新增的元数据会按照从小到大的顺序排序。
在StoreFile中,如果使用BloomFilter,则StoreFile将会把BloomFilter的信息保存到HFile中的元数据中, 元数据块中只保存元数据的value值,key值保存在元数据索引块中。格式如下:
Meta Block Magic {‘M’, ‘E’, ‘T’, ‘A’, ‘B’, ‘L’, ‘K’, 99 } |
Meta Data Value |
Meta Block Magic {‘M’, ‘E’, ‘T’, ‘A’, ‘B’, ‘L’, ‘K’, 99 } |
Meta Data Value |
…… |
每个元数据由元数据头+元数据值组成。
fileInfo中保存的信息为key-value类型的值,其中key与value都是byte[]类型。每个新增的值在内部都以值key顺序从小到大进行排序。fileInfo保存了与该HFile相关的一些信息,其中有系统保留的一些固定的值,这些值的key以”hfile.”为前缀。也可以保存用户自定义的一些值,但这些值的key不能以”hfile.”开头。其中系统内部保留的一些值如下:
项 | key(字符串表示,实际以二进制存储) | value |
LASTKEY | hfile.LASTKEY | 该HFile中的数据块中的最后一个值的key, 该值如果为空则不进行保存 |
AVG_KEY_LEN | hfile.AVG_KEY_LEN | 该HFile中的数据块中的所有值key的平均长度。 |
AVG_VALUE_LEN | hfile.AVG_VALUE_LEN | 该HFile中的数据块中的所有值value的平均长度。 |
COMPARATOR | hfile.COMPARATOR | 在HFile中的数据块中的值都是以值的key进行排序来存放的,而key的组成比较复杂,这就需要一个key的比较器类,而该值保存了key值比较器的类的名称。 |
fileInfo在HFile中的格式如下:
filInfo中所有值(key-value对)的个数,整型 | ||
key | value类型标识 | value |
key | value类型标识 | value |
…… |
fileInfo各项说明:
1. filInfo中所有值(key-value对)的个数,整型,四字节。
2. key值,保存fileInfo中值得key值。在HFile中的组成为
key长+key
其中key长以压缩的整型保存,整型类型包括(byte,short,int,long),如果该整数用i表示,详细说明如下:
1. 当-112 <= i <= 127 时,用一个字节保存实际值。
2. 其他情况下,第一个字节表示该整型与正负与该整数占字节长度,随后存储的是从该整数补码的高位算起的第一个非0字节的所有值。如果第一个字节为v,详细说明如下:
a) 当-120<=i<=-113时,表示该值为正数,该数所占字节为-(v+112)
b) 当-128<=i<=-121时,表示该值为负数,该数所占字节为-(v+120)
例如:
原始值 | 压缩后,以字节表示 | 说明 |
-87 | {-87} | 第一种情况 |
127 | {127} | 第一种情况 |
-1246 | {-122} + {4, -35} | 第二种情况的b类型。{-122}表示该数为负数,并且所占字节长度为-(-122+120)=2字节。其中{4,-35}保存的是-1246的补码1245的第一个非0字节开始的所有字节。1245的16进制为0x04DD,非0字节共2个,第一个为0×04(4),第二个为0xDD(-35),组合一起为{-122, 4,-35} |
130 | {-113} + {-126} | 第二种情况的a类型。{-113}表示该数为正数,并且所占字节长度为-(-113+112)=1字节。其中{-126}保存的是130的补码130的第一个非0字节开始的所有字节。130的16进制为0x04DD,非0字节共2个,第一个为0×04(4),第二个为0×82(-126),组合一起为{-113, -126} |
3. value值,保存fileInfo中值的value值。在HFile中的组成为
value长+value
其中value长以压缩的整型保存,压缩整型具体格式参考key值中关于压缩整型的说明。
数据块索引保存的是每一个数据块在HFile文件中的位置、大小信息以及每个块的第一个cell的key值。格式如下:
Index Block Magic {‘I’, ‘D’, ‘X’, ‘B’, ‘L’, ‘K’, 41, 43 } | ||
block offset | block size | block first key |
block offset | block size | block first key |
…… | ||
block offset | block size | block first key |
格式各项说明:
1. block offset 块在HFile中偏移,long(8字节)。
2. block size 块大小,int(4字节)。
3. block first key 块中第一个cell(key-value)值得key.该值的组成为(key的长(压缩整型表示)+key值)
该数据块的格式与数据库索引相同,元数据块索引保存的是每一个元数据在HFile文件中的位置、大小信息以及每个元数据的key值。格式如下:
Index Block Magic {‘I’, ‘D’, ‘X’, ‘B’, ‘L’, ‘K’, 41, 43 } | ||
meta offset | meta size | meta name |
meta offset | meta size | meta name |
…… | ||
meta offset | meta size | meta name |
格式各项说明:
1. meta offset 元信息在HFile中偏移,long(8字节)。
2. meta size 元信息数据大小,int(4字节)。
3. meta name 元信息中的key值.该值的组成为(key的长(压缩整型表示)+key值)
文件尾主要保存了该HFile的一些基本信息。格式比较简单,如下:
Trailer Block Magic {‘T’, ‘R’, ‘A’, ‘B’, ‘L’, ‘K’, 34, 36 } |
FileInfo Offset (long) |
Data Index Offset (long) |
Data Index Count (int) |
Meta Index Offset (long) |
Meta Index Count (int) |
Total Uncompressed Bytes (long) |
Entry Count (int) |
Compression Codec (int) |
Version (int) |
说明如下:
1. FileInfo Offset – FileInfo信息在HFile中的偏移。long(8字节)。
2. DataIndex Offset – 数据块索引在HFile中的偏移。long(8字节)。
3. DataIndex Count – 数据块索引的个数。int(4字节)。
4. MetaIndex Offset – 元数据索引块在HFile中的偏移。long(8字节)。
5. MetaIndex Count – 元数据索引块的个数。int(4字节)。
6. TotalUncompressedBytes – 未压缩的数据块部分的总大小。long(8字节)。
7. Entry Count – 数据块中所有cell(key-value)的个数。int(4字节)
8. Compression Codec – 压缩算法为enum类型,该值表示压缩算法代码。(LZO-0,GZ-1,NONE-2),int(4字节)
9. Version – 版本信息。当前该版本值为1. int(4字节)。
引用:http://blog.sae.sina.com.cn/archives/3727